sed: 複数行ブロックを標準入力に置き換える

sed: 複数行ブロックを標準入力に置き換える

一方input_file:

1
2
START
foo
END
3

ターゲットSTARTinclude ...ブロック内の内容をENDstdinの複数行の内容に置き換えます。

1
2
hello 
world
3

私が試したこと:

sed '/^START$/,/^END$/d;r /dev/stdin' input_file <<EOF 
hello
world
EOF

残念ながら、結果は

1
hello
world
2
3

r /dev/stdin順番に呼び出されると思います。後ろに /^START$/,/^END$/d;最初の行の後にのみ追加します。

2回目の試み:

sed '/^START$/,/^END$/{d;r /dev/stdin
}' input_file <<EOF     
hello
world
EOF

印刷

1
2
3

上記のコマンド(特に最後のコマンド)が誤った結果を出力するのはなぜですか?どのように調整しますか?

答え1

アドレス範囲は最初の試みでのみ機能しますd。 (append r /dev/stdin...)が最初の行で完了すると、ファイルの終わりに会います。 2回目の試みでは、スクリプトはコマンドrを検出できませんでした。man sed:

  d      Delete pattern space.  Start next cycle.

したがって、d命令の後のすべての内容は(そのアドレス範囲内で)失われますr /dev/stdin

目標を達成するには、以下を試してください。

sed -e '/^START$/,/^END$/ { r /dev/stdin' -e';d};' file3 <<EOF 
hello
world
EOF

1
2
hello
world
3

アドレス範囲が満たされたら、最初に読み取ってからアドレス範囲を削除します。

関連情報