文字列を検索し、範囲の前後のすべての内容を印刷します。

文字列を検索し、範囲の前後のすべての内容を印刷します。

私はこのファイルを持っています:

sometext1{
string1
}

sometext2{
string2
string3
}

sometext3{
string4
string5
string6
}

このファイルから特定の文字列を検索し、その文字列より前のすべての項目を最初から印刷し、{その文字列の後のすべての項目を最後まで印刷したいと思います}。これを達成するためにsedを使用してみましたが、範囲内のすべての内容を印刷しようとすると、たとえば/{/,/string2/sedは次のように印刷します。

sometext1{
string1
}

sometext2{
string2
sometext3{
string4
string5
string6
}

文字列「string2」を検索すると、次のような出力が必要です。

sometext2{
string2
string3
}

ありがとうございます。

ベストアンサー1

これには2つのコマンドがあります。.*{$シーケンスの最後の行まで切り捨てるコマンドが必要な場合(@don_crisstiがそうであるようにedあなたはできます:

sed 'H;/{$/h;/^}/x;/{\n.*PATTERN/!d'

...これは、ewline文字Hの後の前のスペースに各行を追加し\nh一致する各行の前のスペースを上書きし、{$一致する各行の前のhスペースとパターンスペースを置き換え^}てバッファをフラッシュする方法で機能します。

これはewline{に一致する行のみを印刷し、\n特定PATTERNのポイントから印刷します。これはバッファスワップの直後にのみ発生します。

{$シーケンスの最後の一致まで、一連の一致からすべての行を削除しますが、含まれているすべての行を取得できます。たとえば、次のようになります。

sed '/PATTERN.*\n/p;//g;/{$/,/^}/H;//x;D'

それがすることは、h各シーケンスのパターンと前の空白を置き換え...{$.*^}.*、シーケンスのすべての行を前の行文字のH後の前のスペースに追加し\n、各行を繰り返してパターンスペースに最初に現れるewline文字をD削除することです。\nその後、残りのコンテンツから始めてください。

もちろん、\nパターン空間でewlineを取得する唯一の時間は、入力行が一致する場合^}(範囲の終わり)であるため、他の場合にスクリプトを再実行すると、通常どおり次の入力行が取得されます。

ただし、PATTERNewlineと同じパターンスペースにある場合は、\nバッチを上書きする前に印刷してください。^}(範囲を終了してバッファをフラッシュできるように)

この入力ファイルが与えられると(お金ありがとうございます):

sometext1{
string1
}

sometext2{
PATTERN
string3
}

sometext3{
string4
string5
string6
}

Header{
sometext4{
some string

string unknown

here's PATTERN and PATTERN again
and PATTERN too
another string here
}
}

最初のものは次のように印刷されます。

sometext2{
PATTERN
string3
}
sometext4{
some string

string unknown

here's PATTERN and PATTERN again
and PATTERN too
another string here
}

...そして2番目の...

sometext2{
PATTERN
string3
}
Header{
sometext4{
some string

string unknown

here's PATTERN and PATTERN again
and PATTERN too
another string here
}

おすすめ記事