我当前的脚本是这样的:
replacement="Hello"
sed -i 's/(^TEXT_BLOCK=).*/1replacement/' path
我希望能够替换变量TEXT_BLOCK位于我的配置文件与变量替换的内容。我试过1$replacement和1#replacement,但它们都没有给我想要的结果。
像这样硬编码它对我有用,但我不想硬编码。我希望能够分配TEXT_BLOCK变量的值:
sed -i 's/(^TEXT_BLOCK=).*/1Hello/' path
对于一个简单的替换,sed -i "s/^\(TEXT_BLOCK=\).*/\1$replacement/" path
将工作。
当replacement具有特殊字符时,您希望在sed命令中使用不同的分隔符。
replacement="with a /"
delim=$' 01'; sed 's'${delim}'(^TEXT_BLOCK=).*'${delim}'1'"$replacement"${delim} path
然而,当替换具有&
时,这仍然会失败。这个字符也会在<<解决方案>
replacement="Hello"
t='TEXT_BLOCK'
awk -v r="${replacement}" -v key=${t} '{sub("^" key "=.*",key "=" r );print}'
当您也想捕获这样的替换值时,您可以使用
replacement="Hello /& <- strangers"
t='TEXT_BLOCK'
awk -v r="${replacement//&/\\&}" -v key=${t} '{sub("^" key "=.*",key "=" r );print}'
请注意,评论中建议的sed
一行代码(sed -i "s/^\(TEXT_BLOCK=\).*/\1$replacement/" path
)不适用于$replacement
的某些值。
。,如果变量包含/
,则会得到:
replacement="Hello/"
echo 'TEXT_BLOCK=init' | sed -e "s/^\(TEXT_BLOCK=\).*/\1$replacement/"
# → sed: -e expression #1, char 30: unknown option to `s'
虽然OP的问题被标记为sed
,我建议写一些perl -wpe
一行代码代替,有一个更健壮的脚本,并且考虑到perl
是一个相当标准的依赖项,它应该在OP的目标机器上可用。
s///
和BEGIN{ }
。
概念证明:
#!/usr/bin/env bash
subst() {
re="$1"
str="$2"
perl -wpe 'BEGIN {$re=shift @ARGV; $str=shift @ARGV;}; s/$re/$str/g;' "$re" "$str"
}
# Usage example
echo $'TEXT_BLOCK="init"nEnd.' | subst '^TEXT_BLOCK=.*$' 'TEXT_BLOCK="3$/"'
# will print:
# TEXT_BLOCK="3$/"
# End.
注意,这可以很容易地适应sed -i
用例:
#!/usr/bin/env bash
subst_i() {
fil="$1"
re="$2"
str="$3"
perl -i -wpe 'BEGIN {$re=shift @ARGV; $str=shift @ARGV;}; s/$re/$str/g;' "$re" "$str" "$fil"
}
# Usage example
echo $'TEXT_BLOCK="init"nEnd.' > data.txt
subst_i data.txt '^TEXT_BLOCK=.*$' 'TEXT_BLOCK="3$/"'
cat data.txt