文字列を検索し、範囲内の前後のすべてを出力します


9

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

sometext1{
string1
}

sometext2{
string2
string3
}

sometext3{
string4
string5
string6
}

このファイルで特定の文字列を検索し、この文字列の前から始まりまで、{およびこの文字列の後から終わりまでのすべてを印刷します}。私はsedでこれを達成しようとしましたが/{/,/string2/、たとえばsedでこの範囲のすべてを印刷しようとすると、次のように印刷されます。

sometext1{
string1
}

sometext2{
string2
sometext3{
string4
string5
string6
}

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

sometext2{
string2
string3
}

ありがとう。


さて、後でそれらを削除するには、元のファイルの出力の行番号が必要であることがわかりました。@mikeservが提供するコマンドを変更できないか試しましたが、sedのホールド機能と少し混乱しています。
ロドリゴ2015年

まあ、そうねえ、ロドリゴ、あなたは誰にも言わなかった。できますが、のように行うのが最善grep -n '' <infile | sed ...です。sedコマンドは、修飾が必要になります。特に、最上位のアンカーを探す/アドレス/ビット^。したがって、私の答えを使用している場合は、おそらく次のようにすることができますgrep -n '' | sed 'H;/{$/h;/^[^:]*:}/x;/{\n.*PATTERN/!d'。すべての出力行には、元のファイルの行番号の前にコロンなどが付加さ1:sometext1{\n2:string1れます。sed各出力行が番号で開くことを除いて、以前にフィルタリングするものだけをフィルタリングします。
mikeserv 2015

回答:


9

ここに2つのコマンドがあります。(@don_crisstiがで行うように.*{$シーケンスの最後の行までトリムするコマンドが必要な場合は、次のようにすることができます。ed

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

...これは、すべての行をewline文字のH後にある古いスペースに追加し、に一致するすべての行の古いスペースを\n上書きしh、一致するすべての行の古いスペースとパターンスペースを{$入れ替えることによって機能し、それによってバッファをフラッシュします。h^}

{次に、\newlineに一致し、ある時点で一致する行のみを出力します。これはPATTERN、バッファースワップの直後にのみ発生します。

それ{$はシーケンスの最後までの一連のマッチのすべての行を省略しますが、それらのすべてを包括的に取得できます:

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

シーケンスhごとにパターンと古いスペースをスワップ...{$.*^}.*し、シーケンス内のすべての行をewline文字のH後にある古いスペースに追加し、すべてのラインサイクルでパターンスペースで最初に出現するewline文字まで削除してから、残っているものから再開します。\nD\n

もちろん、\nパターンスペースでewlineが発生するのは、入力ラインが一致^}したとき(範囲の終わり)だけです。そのため、他の機会にスクリプトを再実行すると、通常どおり次の入力ラインを取得します。

PATTERN\newline と同じパターンスペースで見つかった場合、ロットを^}再度上書きする前にロットを印刷します(範囲を終了してバッファをフラッシュすることができます)

この入力ファイルが与えられた場合(donに感謝)

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
}

@don_crissti-私は知らない。で始まる行のシーケンスを区切るだけ}です。これは次のような場合にopen{\nsub;\n{ command; }\n}; close
役立ち

こんにちは@mikeserv-私がここで提起した同様の質問unix.stackexchange.com/questions/232509/…、あなたのソリューションは小さなファイルで機能しますが、大きなファイルがあり、「ホールドスペースがオーバーフローしました」と表示されます。エラーメッセージ。万が一、どうすれば解決できますか?多くの感謝
Narayan Akhade

@NarayanAkhade-いいえ。とにかく、オーバーホールなしではありません。でない限り... {...}ブロックに含まれていない大きな入力の広がりはありますか?それが事実であり、最初のソリューションを使用している場合/{$/,/^}/Hは、単にの代わりに、最初に行うことができますH。しかし、2番目の解決策を試しても同じエラーが発生する場合は、その解決策が既に実行されているため、解決できない可能性があります。またed、値引きもしないでください。ドンさんが持って非常に良いここに答えがあり、ed一時的なバッファを使用するために適用することができ、ファイルを MEMはオーバーランをバッファ防ぐべき、としても非常に簡単。
mikeserv 2015

6

ここに解決策がありedます:

ed -s filename <<< $'g/PATTERN/?{?,/}/p\nq\n'

あれは:

g/PATTERN/     # mark each line matching PATTERN  
?{?,/}/p       # for each marked line, print all lines from the previous { up to the next }  
q              # quit editor

これはPATTERN、各ペアの間に1行しかないことを前提としてい{ }ます。そうしないとPATTERN、同じブロック内にある追加の各行に対して重複した出力が得られます。
これは{ }PATTERNたとえばPATTERN、2つの異なるセクションにあるテストファイルの場合、単一行の一致を含む複数に対して機能します。

sometext1{
string1
}

sometext2{
PATTERN
string3
}

sometext3{
string4
string5
string6
}

Header{
sometext4{
some string

string unknown

here's PATTERN again

another string here
}
}

ランニング

ed -s sample <<< $'g/PATTERN/?{?,/}/p\nq\n'

出力:

sometext2{
PATTERN
string3
}
sometext4{
some string

string unknown

here's PATTERN again

another string here
}

私は実際にこれから多くを取りました!どうもありがとう!
mikeserv 2014

このコマンドが存在することすら知りません。ありがとう
ロドリゴ

4

pcregrep

pcregrep -M '(?s)\{[^}]*PATTERN.*?\}'

または、GNUがgrep提供されている場合、入力にNULバイトが含まれていません。

grep -Poz '.*(?s)\{[^}]*PATTERN.*?\}'

0
$ awk 'BEGIN{RS="\n\n"; FS="[{}]"} {if ($2 ~ /string4/) {print $2}}' t1.txt
string4
string5
string6

どこ:

  • string4 ->照合する文字列
  • t1.txt ->クエリで言及されたファイルコンテンツが含まれます

-2

sed -n '/ string / p' filename

-nをsedに追加すると、sedのデフォルトの動作が抑制されます。このステートメントでは、期待どおりの結果が得られない可能性がありますが、文字列を置き換えます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.