Misalkan saya ingin mencari seluruh pohon untuk semua file CPP di mana "Foo" terjadi. Saya mungkin melakukannya:
find . -name "*.cpp" | xargs grep "Foo"
Sekarang anggaplah saya ingin mendaftar hanya contoh-contoh di mana beberapa string lain, katakan "Bar" tidak terjadi dalam 3 baris dari hasil sebelumnya.
Jadi diberikan dua file:
a.cpp
1 Foo
2 qwerty
3 qwerty
b.cpp
1 Foo
2 Bar
3 qwerty
Saya ingin membuat pencarian sederhana di mana "Foo" dari a.cpp ditemukan, tetapi "Foo" dari b.cpp tidak.
Apakah ada cara untuk mencapai ini dengan cara yang cukup sederhana?
Jawaban:
Dengan
pcregrep
:Kuncinya ada pada
-M
opsi yang unikpcregrep
dan digunakan untuk mencocokkan banyak baris (pcregrep
menarik lebih banyak data dari file input seperlunya saat menjalankan RE menuntutnya).(?!...)
adalah operator RE-negatif look-depan perl / PCRE.Foo(?!...)
cocokFoo
selama...
tidak cocok dengan yang berikut....
being(?:.*\n){0,2}.*Bar
(.
tidak cocok dengan karakter baris baru), yaitu dari 0 hingga 2 baris diikuti oleh baris yang berisiBar
.sumber
pcregrep
? Saya belum pernah mendengarnya sebelumnya.(?!...)
negatif di masa depanperl
.Sudahlah, gunakan saja
pcregrep
seperti yang disarankan oleh @StephaneChazelas.Ini seharusnya bekerja:
Idenya adalah menggunakan
-A
saklar grep untuk menampilkan garis yang cocok dan garis N berikut. Anda kemudian meneruskan hasilnya melalui agrep Bar
dan jika itu tidak cocok (keluar> 0), maka Anda mengulangi nama file.Jika Anda tahu Anda memiliki nama file yang waras (tanpa spasi, baris baru atau karakter aneh lainnya), Anda dapat menyederhanakan untuk:
Sebagai contoh:
Perhatikan bahwa
c.cpp
dikembalikan meskipun mengandungBar
karena garis denganBar
lebih dari 3 baris setelahFoo
. Anda dapat mengontrol jumlah baris yang ingin Anda cari dengan mengubah nilai yang diteruskan ke-A
:Ini yang lebih pendek (dengan asumsi Anda menggunakan
bash
):PENTING
Seperti yang ditunjukkan Stephane Chazelas dalam komentar, solusi di atas juga akan mencetak file yang tidak mengandung
Foo
sama sekali. Yang ini menghindari itu:sumber
Foo
. Anda memiliki kutipan yang hilang.Foo
dan saya memperbaikinya tetapi saya tidak mengerti maksud Anda tentang banyak contohFoo
. Itu harus berurusan dengan mereka dengan benar.Belum diuji, saya di ponsel saya:
sesuatu seperti itu.
sumber