
bash スクリプトのテキスト ファイルで一致した行の後に複数の行を追加したいです。この作業にどのツールを選択するかは特に気にしませんが、私にとって重要なのは、スクリプト内で追加する行を「そのまま」指定することです (つまり、追加する行を格納するファイルを生成せずに)。そのため、行は Bash 変数に格納され、行内の何も引用符で囲んだりエスケープしたりする必要がなくなります。この目的には、「引用符で囲んだ」ヒアドキュメントを使用するとうまくいきます。次に例を示します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
OK、以下を使用して 1 つの方法を見つけました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'"