連続する2行の内容に基づいてディレクトリをgrepするにはどうすればよいですか?


11

「Foo」を含む行のディレクトリをgrepする方法はありますが、次の行にも「Bar」が含まれている場合にのみ一致を取得できますか?


現在、問題は元のバージョンとは完全に異なります:/古いバージョンを元に戻して別のバージョンをPOSTする方がよいでしょうか?さらに、新しい質問は私には明確ではありません。
Gilles Quenot、2012年

@sputnick-どのようにですか?質問を最初に投稿したときにディレクトリを指定しました。人々が気づかなかったので、私はそれを太字にしました。
ネイサンロング、

気にしないでください。これでうまくいきます。それに応じてPOSTを編集します。
Gilles Quenot、2012年

回答:


7

@ warl0ckはで正しい方向を示しましたがpcregrep、「is」ではなく「contains」と言い、ファイルではなくディレクトリについて尋ねました。

これは私にはうまくいくようです。

pcregrep -rMi 'Foo(.*)\n(.*)Bar' .

6

Grep自体はそれをサポートしていないようです。代わりにpcregrepを使用してください:

Foo
Bar
Foo
abc

pcregrep -M "Foo\nBar" file

取得:

Foo
Bar

3
OPはそれを言いませんでしたFooそしてBar、行全体を含むことになります。
tojrobinson

6

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 spacehold space HERE

grymoire.comは、shellプログラミングに関して非常に優れています。


どういうh, n, H, x, p, q意味ですか?とても興味深い。
山猫2012年

私のコメントを見てください。pattern space&に関する詳細hold spacegrymoire.com/Unix/Sed.html#uh-56またはフランス語のコメントcamarche.net/faq/9536-sed-introduction-a-sed-part-i
Gilles Quenot

ディレクトリで動作するように調整されたPOST
Gilles Quenot

4

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'
Nathan Long

また、同じ行に「Foo」と「Bar」の両方があるオカレンスもリストされます。
manatwork 2012年

@manatwork:「Foo」と「Bar」を含む行は、「Foo」を含む行です。これは、要求されたものです。
tojrobinson

1
@tojrobinson、「次の行にも「Bar」が含まれている場合にのみ一致を取得する」についてはどうですか?pastebin.com/Yj8aeCEA
manatwork

3

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

1
クールなトリックなんて-z。式全体の前後に「(。*)」があると、一致した行全体が出力されます。現時点では、「Foo」の前と「Bar」の後の部分文字列は表示されません。
manatwork 2012年

1

awkで:

awk '/bar/ && prev != "" {print FILENAME ": " prev "\n" FILENAME ": " $0}
     /foo/ {prev=$0; next}
     {prev=""}' file1...

(awkの制限に関する一般的な注意:一部のファイル名に「=」文字が含まれている可能性がある場合./filenamefilename、awkの代わりにそれらを渡す必要があることに注意してください)

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