sed を使用:
#!/bin/sed -nf
/HD loop$/ {
x
G
N
p
s/.*\n\([^\n]*\)/\1/
}
h
行末($
文字で示す)に「HD loop」が見つかると、コマンドブロックが実行されます。x
このコマンド ブロックは、 exchange コマンドを使用して、ホールド スペース (補助バッファー) の内容をパターン スペース (作業バッファー) の内容と交換することから始まります。後で見るように、最後の行が読み取られたホールド スペースを保持します。このG
コマンドはホールド スペース (現在の行を含む) の内容をパターン スペースに追加し、N
コマンドは入力の次の行を読み取ってパターン スペースに追加します。次に、パターン空間をp
指図。最後に行うことは、ホールド スペースを復元することです。これを行うには、2 つのコマンドを使用します。1 つ目は、パターン スペースから最後の行を除くすべての行を削除する代替コマンドです。次に、コマンドでスペースを保持するためにパターン スペースをコピーしますh
。
「HD ループ」は行が一致しなくてもホールドスペースにコピーされます。これにより、保留スペースには常に前の行の内容が含まれます。一致が見つかった後にホールド スペースを設定する方法が原因で、連続する行に表示される 2 つの一致が正しく認識されないことに注意してください。これを考慮したい場合は、特別な処理が必要です。
#!/bin/sed -nf
/HD loop$/ b next
h
:start
n
/HD loop$/ {
x
G
:next
N
p
s/.*\n\([^\n]*\)/\1/
/HD loop$/ b next
d
}
h
b start
より完全で一般的なバージョンを作成するには、最初の行に「HD ループ」が見つかった場合に何が起こるかをまず検討する必要があります。以前のバージョンでは、空の行の後に「HD ループ」行が出力されていました。これにより、実際には HD ループの前に空の行があると出力が混乱する可能性があるため、これには特別な処理を使用する必要があります。特別な処理は、sed の評価ループを独自のものを使用してオーバーライドすることです。
ループの開始を定義するコマンドでstart
ラベルを定義します。:
次に、スクリプトの最後で、b
branch コマンドを使用してループの先頭に戻ります。sed の評価ループを完全に模倣するには、start
ラベルの 後の最初のコマンドがn
次のコマンドになり、次の入力行をパターン空間に読み込みます。
ループを定義すると、最初の行が HD ループで始まる特殊なケースを処理できます。含まれている場合は、ホールド スペースの内容の読み込みをスキップする必要があります。これは、ホールド スペースには有用なデータが含まれていないことがわかっているためです。ホールド スペースの内容を追加するコマンドnext
の直後にラベルを定義しましょう。G
を使用/HD loop/ b next
して、ホールド スペース操作をスキップし、現在の行と次の行だけを出力できます。
最初の行が「HD ループ」で始まらない場合は、n
別のコマンドで置き換える前にホールド スペースに格納する必要があります。したがって、h
コマンドでそれを行います。
次の特殊なケースは、2 つの「HD ループ」ラインが連続して表示される場合です。その場合、以前のバージョンのブロックの最後で、新しく読み取った行に「HD ループ」が含まれているかどうかを確認できます。含まれている場合は、単にnext
ラベルに戻って別の行を読み取り、それを印刷します。これを必要なだけ何度でも行うことができ、利用可能な連続した「HD ループ」ラインをいくつでも処理できます。
最後の特別なケースは、2 つの「HD ループ」行が 1 行で区切られて表示される場合です。そのままにしておくと、この場合、「HD ループ」行の間の行が 2 回印刷されます。これを処理するには、一致の直後に「HD ループ」行が見つかった場合、ホールド スペースを出力する必要がないかのように動作する必要があります。この状況は、入力の最初の行を調べているときに起こることと似ているためd
、一致の最後で delete コマンドを使用して、パターン スペースをクリアし、スクリプト全体を再起動できます。行が最初の入力行であるかのように動作し、一致の後の行が「HD ループ」行である場合、ホールド スペースを出力しません。
更新: 最初の結果のみが必要な場合は、いくつかのことを単純化できます。
#!/bin/sed -nf
/HD loop$/ b next
h
:start
n
/HD loop$/ {
x
G
:next
N
p
q
}
h
b start
ここで、行を印刷した後に以前のすべての操作を実行する代わりに、q
コマンドで終了することができます。
これが役立つことを願っています=)