Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 如何使用行号bash脚本用字符串变量替换文件中的特定行?_Linux_Bash_Sed - Fatal编程技术网

Linux 如何使用行号bash脚本用字符串变量替换文件中的特定行?

Linux 如何使用行号bash脚本用字符串变量替换文件中的特定行?,linux,bash,sed,Linux,Bash,Sed,以下是target.txt文件的内容: line1 line2 Environment=xLink=https://11111/route line4 line5 我正在尝试编写一个bash脚本,该脚本将查找包含“https”的行的编号,然后用bash脚本中获得的新字符串变量替换整行,下面是没有替换行的bash脚本: #!/bin/bash x="12345" route="/route" x_route="${x}${route}"

以下是target.txt文件的内容:

line1
line2
Environment=xLink=https://11111/route
line4
line5
我正在尝试编写一个bash脚本,该脚本将查找包含“https”的行的编号,然后用bash脚本中获得的新字符串变量替换整行,下面是没有替换行的bash脚本:

#!/bin/bash

x="12345"
route="/route"
x_route="${x}${route}"
x_init="Environment=xLink=https://"
new_line="${x_init}${x_route}"

echo "${new_line}"

to_replace_line_number=$(find target.txt -type f | xargs grep -n 'https' | cut -c1-2)

echo "${to_replace_line_number}"

targetfile=target.txt

echo "${targetfile}"
调用此脚本将按预期输出以下内容:

Environment=xLink=https://12345/route
3:
target.txt
现在,在没有bash脚本的情况下,如果调用:

sudo sed -i '3 c\Environment=xLink=https://12345/route' target.txt
target.txt会根据需要更改为:

line1
line2
Environment=xLink=https://12345/route
line4
line5
但目标是自动化,所以我尝试使用sed命令在bash脚本中完成这项工作。到目前为止,我尝试了两种方法,但都不奏效

方法1: 我在bash脚本中添加了以下行:

sudo sed -i "${to_replace_line_number}s/.*/${new_line}/" ${targetfile}
sudo sed -i "${to_replace_line_number} c\${new_line}" ${targetfile}
当我运行脚本时,它不起作用,我得到了以下错误:

sed: -e expression #1, char 2: : doesn't want any addresses
sed: -e expression #1, char 2: : doesn't want any addresses
方法2: 我在bash脚本中添加了以下命令:

sudo sed -i "${to_replace_line_number}s/.*/${new_line}/" ${targetfile}
sudo sed -i "${to_replace_line_number} c\${new_line}" ${targetfile}
当我运行脚本时,它不起作用,我得到了以下错误:

sed: -e expression #1, char 2: : doesn't want any addresses
sed: -e expression #1, char 2: : doesn't want any addresses

我到底错过了什么?非常感谢您的帮助。

\
是一个特殊字符,因此当您在双引号中使用它时,必须将其转义:

# Set example values and create a test file:
to_replace_line_number="3"
new_line="Environment=xLink=https://12345/route"
targetfile="test.txt"
printf 'line%d\n' {1..5} > "$targetfile"

# The actual command
sudo sed -i "${to_replace_line_number} c\\${new_line}" "${targetfile}"
这将使它相当于您的手动调用

如果您想知道为什么与
r
y
相比,
c
的文档格式显得奇怪,那是因为
\
后面的换行符是故意的。这是POSIX的实现方式:

sudo sed -i "${to_replace_line_number} c\\
${new_line}" "${targetfile}"

这是因为在读取行号时去掉了两个字符。因此,变量中会弹出一个额外的“:”。相反,只取出一个字段,它应该可以正常工作

替换

to_replace_line_number=$(find target.txt -type f | xargs grep -n 'https' | cut -c1-2)


当前代码存在几个问题:

# parse the `grep -n` by having `cut` pull everthing before the (first) `:`

$ to_replace_line_number=$(find target.txt -type f | xargs grep -n 'https' | cut -d":" -f1)
$ echo "${to_replace_line_number}"
3

# modification to @thatotherguy's `sed/c` suggestion to allow all code to go on a single line:

$ sed -i -e "${to_replace_line_number} c\\" -e "${new_line}" ${targetfile}
$ cat "${targetfile}"
line1
line2
Environment=xLink=https://12345/route
line4
line5
  • 替换行号
    =
    3:
    -注意冒号(
    );这被输入到
    sed
    命令中,例如:
    sed-i“3:c\…
    ,并生成错误消息,说明第二个字符的问题,即
  • 正如@thatotherguy在他的回答中指出的,
    c\
    选项需要一个转义字符和一个嵌入式回车符……或者
对OPs当前代码的最小更改:

# parse the `grep -n` by having `cut` pull everthing before the (first) `:`

$ to_replace_line_number=$(find target.txt -type f | xargs grep -n 'https' | cut -d":" -f1)
$ echo "${to_replace_line_number}"
3

# modification to @thatotherguy's `sed/c` suggestion to allow all code to go on a single line:

$ sed -i -e "${to_replace_line_number} c\\" -e "${new_line}" ${targetfile}
$ cat "${targetfile}"
line1
line2
Environment=xLink=https://12345/route
line4
line5

有几种方法可以用来查找和替换所需的行,而不是派生子进程调用来获取行号

一个
sed
想法:

sed -i "s|^.*https.*$|${new_line}|" ${targetfile}
其中:

  • |
    -使用管道作为
    sed
    分隔符,因为
    ${new_line}
    包含前斜杠
  • ^.*https.*$
    -匹配包含字符串
    https
  • ${new\u line}
    -将该行替换为
    ${new\u line}
运行上述程序后:

$ cat target.txt
line1
line2
Environment=xLink=https://12345/route
line4
line5

假设
${to_replace_line_number}
=
3:
,您的
sed
将变成:
sed-i“3:c\…
;这似乎与关于字符2的错误消息相匹配;当
sed
能够在不需要任何行号的情况下查找并替换包含
https
的行号时,为什么要跳过查找行号的难关呢?哦,是的,我尝试过这个,但我无法让它工作。我已经在努力让sed做一件特定的事情,用字符串变量替换第3行。我显然还没有准备好,也没有能力在bash脚本中调用一个sed命令来找到行并替换它,您能分享一下您的方法或代码行吗?我已经扩展了我的评论作为答案(见下文);看看你的问题历史,你可能想回顾一下,然后考虑回顾(过去)的答案,那些有益的……只要匹配的行数是<代码> < 10 < /代码>,这是有效的;可能最好使用
cut-d:“-f1
因为这将给出完整的行号,而不管到底有多少位数字(1,2,5,…),我忘了将原来的调用调整到这里的示例中,但我肯定对这两个注释/更正感到满意