ファイルを解析し、特定の2行間のデータを印刷したいと思います。 「範囲開始」から「範囲終了」まで。ただし、「範囲の終わり」が存在する場合にのみ該当します。
ソースファイルが次の場合:
[This is the start] of some data
this is information
this is more information
This is does not contain the ending required
[This is the start] of some other data
this is info I want
this is info I want
[This is the ending I was looking for]
次のように印刷する必要があります。
[This is the start] of some other data
this is info I want
this is info I want
[This is the ending I was looking for]
grepを使用して必要なデータを見つけて上向きに印刷できましたが、行数は固定されていました。
データ行数が一定でない場合は、grepまたはsedを使用して最後の行から始めて、指定された文字列の次の項目を見つけて、目的の特定の範囲をキャプチャする方法はありますか?
データセグメントの「範囲の開始」は、「範囲の開始」と「範囲の終わり」ポイントの間のすべてのデータと一緒に印刷する必要があり、「範囲の終わり」の一致は行の範囲全体を印刷する必要があるかどうかを決定します。範囲(データセグメント)に指定された終わりがない場合は、印刷しないでください。複数のセグメントにエンドポイントがある場合は、エンドポイントを含むすべてのセグメントを印刷する必要があります。入力ファイルには終わりがありますが、開始がないか、単一の始動に複数の終わりがある場合はありません。
2つのパターンの間(および含む)の線を印刷します。一致する最初の行から印刷を開始し、最初の終了セグメントが見つかるまで印刷を続けるため、問題は解決されません。指定された出口ステートメントを含むセグメントのみを印刷する必要があります。
ベストアンサー1
使用sed
:
$ sed -n '/This is the start/{h;d;}; H; /This is the ending/{x;p;}' file
[This is the start] of some other data
this is info I want
this is info I want
[This is the ending I was looking for]
注釈付きsed
スクリプト:
/This is the start/{ # We have found a start
h; # Overwrite the hold space with it
d; # Delete from pattern space, start next cycle
};
H; # Append all other lines to the hold space
/This is the ending/{ # We have found an ending
x; # Swap pattern space with hold space
p; # Print pattern space
};
このスクリプトが行うことは、すべての行を「予約済みスペース」(の共通バッファsed
)に格納することです。しかし、「スタートライン」を見つけたら、そのスペースをリセットします。 「終了行」が見つかると、保存されたデータが印刷されます。
「開始ライン」の前に「終了ライン」があり、間に「開始ライン」がない2つの「エンドライン」が見つかると、これは中断されます。
awk
上記と同じプロセスを実行するプログラムsed
:
$ awk '/This is the start/ { hold = $0; next }
{ hold = hold ORS $0 }
/This is the ending/ { print hold }' file
(上記と同じ出力)