Sed 命令将配置文件中的变量值替换为当前脚本中另一个变量的值?



我当前的脚本是这样的:

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的目标机器上可用。

要编写这样一个脚本,您可以只依赖Perl操作符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

相关内容

最新更新