「Foo」を含む行のディレクトリをgrepする方法はありますが、次の行にも「Bar」が含まれている場合にのみ一致を取得できますか?
「Foo」を含む行のディレクトリをgrepする方法はありますが、次の行にも「Bar」が含まれている場合にのみ一致を取得できますか?
回答:
Grep自体はそれをサポートしていないようです。代わりにpcregrepを使用してください:
Foo
Bar
Foo
abc
pcregrep -M "Foo\nBar" file
取得:
Foo
Bar
FooそしてBar、行全体を含むことになります。
sedスクリプト:
#!/bin/sed -nf
/^Foo/{
h # put the matching line in the hold buffer
n # going to nextline
/^Bar/{ # matching pattern in newline
H # add the line to the hold buffer
x # return the entire paragraph into the pattern space
p # print the pattern space
q # quit the script now
}
}
それを使用するには:
chmod +x script.sed
printf '%s\n' * | ./script.sed
printfここでは1行ごとに現在のディレクトリ内のすべてのファイルを表示し、それを渡しますsed。
注:これはアルファベット順にソートされています。
もっとに関する情報便利なのpattern spaceとhold space HERE。
grymoire.comは、shellプログラミングに関して非常に優れています。
h, n, H, x, p, q意味ですか?とても興味深い。
pattern space&に関する詳細hold space:grymoire.com/Unix/Sed.html#uh-56またはフランス語のコメントcamarche.net/faq/9536-sed-introduction-a-sed-part-i
grepのみを使用して、次のパイプを作成できます。
grep -A1 'Foo' input_file | grep -B1 'Bar' | grep 'Foo'
1つ目grepは、含まFooれるすべての行と、一致後の行を取得します。次に、を含む行とBar一致する前の行を取得し、最後にこの出力からを含む行を抽出しますFoo。
EDIT:としてmanatworkは指摘し、を厳守すべきいくつかの問題の場合があります。興味深い課題ですが、grep「ライン指向の機能」があるため、それを使用したソリューションは「ハック」である可能性が高く、おそらくpcregrep、現在のタスクにより適したものを使用した方がよいでしょう。
find . -name '*.txt' | xargs grep -A1 'Foo' | grep -B1 'Bar'
私pcregrepはを使用したネイサンの解決策を好みますが、これはgrepのみを使用した解決策です
grep -o -z -P 'Foo(.*)\n(.*)Bar' file
オプションの説明:
-o一致した部分のみを印刷します。を含めると-zファイル全体が印刷されるため必要です(どこかに\ 0がない場合)-z 入力を一連の行として扱い、各行は改行ではなくゼロバイト(ASCII NUL文字)で終了します。-P perl regex構文 編集:このバージョンは、一致した行全体を出力します
grep -o -P -z '(.*)Foo(.*)\n(.*)Bar(.*)' file
-z。式全体の前後に「(。*)」があると、一致した行全体が出力されます。現時点では、「Foo」の前と「Bar」の後の部分文字列は表示されません。
awkで:
awk '/bar/ && prev != "" {print FILENAME ": " prev "\n" FILENAME ": " $0}
/foo/ {prev=$0; next}
{prev=""}' file1...
(awkの制限に関する一般的な注意:一部のファイル名に「=」文字が含まれている可能性がある場合./filenameはfilename、awkの代わりにそれらを渡す必要があることに注意してください)