基本上,我想将几行代码从模板文件复制到脚本文件。是否可以使用sed
来复制一个包含与脚本交互的符号的字符串?
我使用了以下线路:
$SWAP='sudo cat /home/kaarel/template'
sed -i -e "s/#pointer/${SWAP}/" "script.sh"
输出为:
./line-adder.sh: line 11: =sudo cat /home/kaarel/template: No such file or directory
不,使用sed不可能稳健地做到这一点。只需使用awk:
awk -v swap="$SWAP" '{sub(/#pointer/,swap)}1' script.sh > tmp && mv tmp script.sh
在GNU awk的最新版本中,如果你关心的话,有一个用于就地编辑的-i inplace
标志。
关于"&&"的观点很好。这是一个真正强大的版本,它将适用于搜索或替换字符串中的任何字符:
awk -v old="#pointer" -v new="$SWAP" 's=index($0,old){$0 = substr($0,1,s-1) new substr($0,s+length(old))} 1'
例如:
$ echo "abc" | awk -v old="b" -v new="m&&n" 's=index($0,old){$0 = substr($0,1,s-1) new substr($0,s+length(old))} 1'
am&&nc
该行存在两个问题:
$SWAP='sudo cat /home/kaarel/template'
第一种是,在执行该行之前,bash
执行变量扩展,并将$SWAP
替换为SWAP
的当前值。这不是你想要的。您希望bash
为SWAP
指定一个值。
第二个问题是右边用单引号括起来,这样可以保护字符串不被扩展。你不想保护字符串不被扩展:你想执行它。要执行它,你可以使用反引号,它们看起来可能相似,但行为却截然不同。
然而,反引号是一种古老的要求执行命令的形式。更现代的形式是$(...)
,它消除了反引号的一些问题。
把所有这些放在一起,使用:
SWAP=$(sudo cat /home/kaarel/template)
sed -i -e "s/#pointer/${SWAP}/" "script.sh"
但是,请注意,如果template
文件中有任何sed活动字符,则sed
命令可能会出现问题。