Pencocokan negatif menggunakan grep (garis kecocokan yang tidak mengandung foo)


991

Saya telah mencoba mencari sintaks untuk perintah ini:

grep ! error_log | find /home/foo/public_html/ -mmin -60

ATAU:

grep '[^error_log]' | find /home/baumerf/public_html/ -mmin -60

Saya perlu melihat semua file yang telah dimodifikasi kecuali untuk yang bernama error_log.

Saya sudah baca di sini , tetapi hanya menemukan satu notpola regex.


13
[^ error_log] tidak akan pernah berhasil, [] adalah kelas char, regexp pada umumnya tidak bagus pada pola negatif (kecuali mesin mengimplementasikan lookaheads negatif).
Jaap

Jawaban:


1758

grep -v adalah temanmu:

grep --help | grep invert  

-v, --invert-match pilih jalur yang tidak cocok

Lihat juga yang terkait -L(pelengkap dari -l).

-L, --files-without-match hanya mencetak nama FILE yang tidak mengandung kecocokan


125
Patut disebutkan bahwa untuk beberapa -epilihan pertandingan (negatif) dapat digunakan:grep -v -e 'negphrase1' -e 'negphrase2'
Babken Vardanyan

31
Mirip dengan komentar dari @ Babken-Vardanyan Also - mampu menggunakan pipa untuk bergabung dengan beberapa pertandingan misalnyagrep -v 'negphrase1|negphrase2|negphrase3'
Nicholas Adams

13
Komentar terakhir TIDAK sama dengan akan mencari hal-hal yang tidak cocok dengan keduanya daripada keduanya. yaitu Jika cocok satu tetapi tidak yang lain masih dicetak. Cobalah keduanya dengan string yang tidak serupa
Evan Langlois

7
@EvanLanglois - memaksa grep untuk menginterpretasikan pola sebagai ekspresi reguler yang diperluas menggunakan -Ekarya, yaitu grep -vE 'negphrase1|negphrase2|negphrase3'
Zlemini

1
@ OlleHärstedt, saya pikir saya salah mengerti skenario Anda di komentar saya sebelumnya, berikut ini mungkin apa yang Anda cari grep "" /dev/null * | grep foo | grep -v bar | cut -d: -f1 | sort -u( mengapa grep pertama?, Selalu ada jalannya :))
Motti

139

Anda juga dapat menggunakan awkuntuk tujuan ini, karena memungkinkan Anda untuk melakukan pemeriksaan yang lebih kompleks dengan cara yang lebih jelas:

Baris tidak mengandung foo:

awk '!/foo/'

Baris yang mengandung tidak foojuga bar:

awk '!/foo/ && !/bar/'

Baris yang tidak mengandung fooatau baryang mengandung salah satu foo2atau bar2:

awk '!/foo/ && !/bar/ && (/foo2/ || /bar2/)'

Dan seterusnya.


2
Itu sebenarnya cukup keren. Anda bahkan tidak perlu mempelajari bahasa awk lengkap untuk mengelompokkan regexp dengan operator logis. Terima kasih atas jawaban ini!
Peter T.

1
Persis apa yang saya cari, terima kasih banyak.
mmrs151

13

Dalam kasus Anda, Anda mungkin tidak ingin menggunakan grep, tetapi tambahkan klausa negatif pada perintah find, mis

find /home/baumerf/public_html/ -mmin -60 -not -name error_log

Jika Anda ingin memasukkan wildcard dalam nama, Anda harus menghindarinya, misalnya untuk mengecualikan file dengan akhiran .log:

find /home/baumerf/public_html/ -mmin -60 -not -name \*.log
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.