2つのコマンドを含むスクリプトをテストしていますsed
。最初のコマンドは入力から行を削除し、2番目のコマンドは入力の最後に行を追加します。
$ cat input.txt
Line 1
Line 2
Line 3
$ sed '/Line 1/d;$aAppended line' input.txt
Line 2
Line 3
Appended line
$ sed '/Line 2/d;$aAppended line' input.txt
Line 1
Line 3
Appended line
今まではそんなに良くなった。ただし、削除するために選択した行が最後に入力された行である場合、スクリプトの2番目のコマンドは実行されません。
$ sed '/Line 3/d;$aAppended line' input.txt
Line 1
Line 2
sed
入力行は一度に読み取られ、それ以上読み取る行がなくなるまで各行でスクリプトが「実行」されるので、私のスクリプトが決して「完了」(つまり追加されていないAppended line
)という事実が意味があることを学びました。 。
それでもこれは私にとって問題になります(まだ追加する必要がありますAppended line
)。この問題についてよく知っている人はいますか?もしそうなら、「標準的な解決策」はありますか?私の考えに代わるもの(最後の行を削除してから1つ追加)は次のとおりです。変える:
$ sed 's/Line 3/Appended line/' file.txt
Line 1
Line 2
Appended line
これが私の唯一の選択ですか?
ベストアンサー1
d
マニュアルページのコマンドsed
:
パターンスペースを削除します。次のサイクルを開始してください。
複数のsed
コマンドが指定された順序で実行されるため、「次のサイクルの開始」は、実際に行が削除された後(現在のサイクルの)削除された行に適用される可能性がある後続のコマンドの実行を停止することを意味します。したがって、Line 3
最後の行で削除されると、新しいループが始まりますa
未定最後の行に適用すべきコマンドは実行されません。
この問題を解決するには、コマンドの順序を逆にするだけです。
sed -e '$aAppended line' -e '/Line 3/d'
またはGNU固有のコードと同等の標準コード:
sed '$a\
Appended line
/Line 3/d'
これにより、最後の行の後にテキストが追加されます。今後 Line 3
削除されます(そしてループは終了します)。
そのa
行は追加されません。空間をパターン化する;引用するPOSIX、それ後で出力するテキスト予約、テキスト[...]入力ラインを取得する前に、標準出力に書き込む必要があります。d
[...] したがって、そのオプションの影響を受けません-n
。