用多行替换文件中的单行时出现问题(BASH)



这是设置,我有两个变量:

$ echo "${ORIGINALSTRING}"
placeholdertext
$ echo "${REPLACEMENTSTRING}"
-----BEGIN CERTIFICATE-----
thisisarandombase64encodedstring
blahblahblahblahblahblahblahblah
blahblahblahblahblahblahblahblah
blahblahblahblahblahblahblahblah
blahblahblahblahblahblahblahblah
-----END CERTIFICATE-----

我需要将文本文件中存在的原始字符串替换为包含多行的字符串。我遇到了sed:的死胡同

$ sed -i "s/${ORIGINALSTRING}/${REPLACEMENTSTRING}/g" ./somedir/file.txt
sed: -e expression #1, char 48: unterminated `s' command

我在同一个命令上尝试了二十多种变体,但最终我发现这是由一个有多行的环境变量引起的。因此,遗憾的是,sed已退出。

有人对如何完成这项任务有其他想法吗?我听说awk可以做我想做的事情,但我还没有看到任何与我的特定用例相关的好例子。

ORIGINALSTRING="$ORIGINALSTRING" REPLACEMENTSTRING="$REPLACEMENTSTRING" awk '
BEGIN {
old = ENVIRON["ORIGINALSTRING"]
new = ENVIRON["REPLACEMENTSTRING"]
}
s = index($0,old) {
$0 = substr($0,1,s-1) new substr($0,s+length(old))
}
{ print }
' file

无论shell变量中有什么字符,以上都会起作用,因为它正在使用文本字符串进行搜索和替换,而如果其中一个或另一个中存在/&1.*^$或各种其他字符,则sed解决方案将失败,因为sed没有使用文本字符串的功能,请参阅是否可以使用sed可靠地转义regex元字符。

我几乎总是建议使用ededit文件,而不是尝试使用非标准的sed -i:

printf "%sn" "g/$ORIGINALSTRING/c" "$REPLACEMENTSTRING" . w | ed -s input.txt

c会将与ORIGINALSTRING匹配的每一行更改为REPLACEMENTSTRING中的行(.表示插入模式的输入结束(,并且w将更改后的文件重新格式化回磁盘。

sed中的等效项需要在除最后一行之外的每一行末尾添加一个\

sed -i "/$originalstring/c\
${replacementstring//$'n'/\$'n'}" input.txt

另请参阅正确的bash和shell脚本变量大小写,并考虑是否应该使用所有大写的变量名。

用sed和bash的多行字符串替换字符串及其参数扩展:

ORIGINALSTRING='placeholdertext'
REPLACEMENTSTRING='-----BEGIN CERTIFICATE-----
thisisarandombase64encodedstring
blahblahblahblahblahblahblahblah
blahblahblahblahblahblahblahblah
blahblahblahblahblahblahblahblah
blahblahblahblahblahblahblahblah
-----END CERTIFICATE-----'
sed -i "s|${ORIGINALSTRING}|${REPLACEMENTSTRING//$'n'/\n}|" file

我从s///切换到s|||

最新更新