我想在 bash 脚本的文本文件中的匹配行之后附加多行。虽然我并不特别关心为这项工作选择什么工具,但对我来说重要的是我想指定脚本中“按原样”附加的行(因此无需生成保存它们的附加文件),以便它们最终出现在 Bash 变量中,并且无需引用/转义其中的任何内容 - 为此,使用“引用”heredoc 对我来说是可行的。这是一个例子appendtest.sh
:
cat > mytestfile.txt <<'EOF'
"'iceberg'"
"'ice cliff'"
"'ice field'"
"'inlet'"
"'island'"
"'islet'"
"'isthmus'"
EOF
IFS='' read -r -d '' REPLACER <<'EOF'
"'$oasis$'"
"'$ocean$'"
"'$oceanic trench$'"
EOF
echo "$REPLACER"
sed -i "/ \"'ice field'\"/a${REPLACER}" mytestfile.txt
不幸的是这不起作用:
$ bash appendtest.sh
"'$oasis$'"
"'$ocean$'"
"'$oceanic trench$'"
sed: -e expression #1, char 39: unknown command: `"'
...因为sed
使用未转义的多行替换时失败。所以我的问题是:
- 我可以使用什么来代替
sed
对一行文本执行匹配,并按照 Bash 变量($REPLACER
在示例中)中指定的方式插入/附加行?
答案1
如果您使用 GNU sed
,最好的选择是使用以下r
命令:
sed -i "/ \"'ice field'\"/ r /dev/stdin" mytestfile.txt <<'EOF'
"'$oasis$'"
"'$ocean$'"
"'$oceanic trench$'"
EOF
答案2
好的,找到了一种使用方法perl
:
cat > mytestfile.txt <<'EOF'
"'iceberg'"
"'ice cliff'"
"'ice field'"
"'inlet'"
"'island'"
"'islet'"
"'isthmus'"
EOF
IFS='' read -r -d '' REPLACER <<'EOF'
"'$oasis$'"
"'$ocean$'"
"'$oceanic trench$'"
EOF
# echo "$REPLACER"
IFS='' read -r -d '' LOOKFOR <<'EOF'
"'ice field'"
EOF
export REPLACER # so perl can access it via $ENV
# -pi will replace in-place but not print to stdout; -p will only print to stdout:
perl -pi -e "s/($LOOKFOR)/"'$1$ENV{"REPLACER"}'"/" mytestfile.txt
# also, with export LOOKFOR, this works:
# perl -pi -e 's/($ENV{"LOOKFOR"})/$1$ENV{"REPLACER"}/' mytestfile.txt
cat mytestfile.txt # see if the replacement is done
输出如所期望的:
$ bash appendtest.sh
"'iceberg'"
"'ice cliff'"
"'ice field'"
"'$oasis$'"
"'$ocean$'"
"'$oceanic trench$'"
"'inlet'"
"'island'"
"'islet'"
"'isthmus'"