「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の代わりにそれらを渡す必要があることに注意してください)