Linux 如何使用行号bash脚本用字符串变量替换文件中的特定行?
以下是target.txt文件的内容: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}"
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\
# 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,…),我忘了将原来的调用调整到这里的示例中,但我肯定对这两个注释/更正感到满意