Bagaimana saya bisa menemukan semua file yang TIDAK mengandung string teks?

40

Apa perintah ringkas yang dapat saya gunakan untuk menemukan semua file yang TIDAK mengandung string teks?

Saya mencoba ini (menggunakan -v untuk membalikkan parameter grep) tanpa hasil:

find . -exec grep -v -l shared.php {} \;

Seseorang berkata ini akan berhasil:

find . ! -exec grep -l shared.php {} \;

Tetapi sepertinya itu tidak berhasil untuk saya.

Halaman ini memiliki contoh ini:

find ./logs -size +1c  > t._tmp
while read filename
do
     grep -q "Process Complete" $filename
     if [ $? -ne 0 ] ; then
             echo $filename
     fi
done < t._tmp
rm -f t_tmp

Tapi itu rumit dan sama sekali tidak ringkas.

ps: Saya tahu itu grep -L *akan melakukan ini, tetapi bagaimana saya bisa menggunakan perintah find dalam kombinasi dengan grep ke file yang dikecualikan adalah apa yang benar-benar ingin saya ketahui.

pss: Juga saya tidak yakin bagaimana agar grep menyertakan subdirektori dengan grep -L *sintaks, tetapi saya masih ingin tahu bagaimana menggunakannya dengan find:)

cwd
sumber
1
Perintah pertama yang Anda tulis bekerja dengan baik di komputer saya. Versi penemuan apa yang Anda gunakan? Dan karena kita berada di dalamnya, mungkin tentukan unix mana yang Anda jalankan ..
rahmu
@rahmu, perintah ini hampir selalu tidak berfungsi seperti yang Anda harapkan. Anda mungkin memiliki kasus yang sangat spesifik. Silakan lihat unix.stackexchange.com/questions/339619/...
sgnsajgon

Jawaban:

8
find . -type f | xargs grep -H -c 'shared.php' | grep 0$ | cut -d':' -f1    

ATAU

find . -type f -exec grep -H -c 'shared.php' {} \; | grep 0$ | cut -d':' -f1

Di sini kita menghitung jumlah baris yang cocok (menggunakan -c) dalam file jika jumlah adalah 0 maka file yang diperlukan, jadi kami memotong kolom pertama yaitu nama file dari output.

Sachin Divekar
sumber
6
Ini sangat rumit. Lihat jawaban Kevin .
Gilles 'SO- berhenti bersikap jahat'
@ Gilles ya saya setuju dengan Anda. Saya memberi +1 jawabannya.
Sachin Divekar
6
Ini tidak hanya "sangat rumit" tetapi salah karena akan juga mencantumkan semua file yang berisi kelipatan 10 baris yang cocok dengan pola. Bahkan jika grepitu diperbaiki ini masih akan menganggap tidak ada nama file yang mengandung :atau karakter baris baru ...
don_crissti
@don_crissti, terima kasih telah menyebutkan! Tetap saja, kecuali Anda menggunakan banyak kode copy-paste, solusi di atas adalah tipu muslihat bagus.
Ufos
@Ufos - Saya benar-benar tidak mendapatkan komentar Anda ... Ini salah . Bagaimanapun, jangan ragu untuk menggunakannya jika itu terlihat seperti "tipu muslihat bagus" untuk Anda ...
don_crissti
57

Temuan Anda akan berfungsi jika Anda mengubah -v -l(file yang memiliki baris yang tidak cocok) ke -L(file tanpa baris yang cocok), tetapi Anda juga bisa menggunakan opsi greprekursif ( -r):

grep -rL shared.php .
Kevin
sumber
menemukan mana yang seharusnya bekerja?
cwd
@ Kevin - maaf, find . -exec grep -v -l shared.php {} \;(dan semua varian lain yang saya coba) tidak berfungsi untuk saya. Saya menggunakan OS X tapi saya pikir itu tidak masalah. Saya memberi Anda +1 karena saya lupa tentang -ropsi itu.
cwd
@ cwd saya tahu ini sudah lama tetapi saya ingin meninggalkan ini untuk pembaca di masa mendatang: fakta bahwa Anda menggunakan OS X memang membuat perbedaan. Mac OSX menggunakan perintah FreeBSD. Kebanyakan orang di sini menganggap perintah gaya Linux (GNU). Mereka memiliki argumen yang berbeda, cara penanganan detail yang berbeda.
Rich Homolka
Pada 2016 OSX tampaknya mendukung-L
David Moles
@ Kevin Saya mengatakan itu, bukan itu tidak. :) tidak ada yang secara eksplisit mengatakan tidak, tapi komentarnya membingungkan (dan saya pasti mengalami masalah OS X / BSD vs GNU lainnya).
David Moles
4

Saya tahu itu grep -L *akan melakukan ini, tetapi bagaimana saya bisa menggunakan findperintah dalam kombinasi dengan grepuntuk mengecualikan file adalah apa yang saya benar-benar ingin tahu

Anda bisa menggunakan finddan grepmenyukai ini:

find . -type f ! -exec grep -q 'PATTERN' {} \; -print

Di sini -printdieksekusi hanya jika ekspresi sebelumnya: ! -exec ... {}dievaluasi sebagai true.
Jadi untuk setiap file yang ditemukan, grep -q 'PATTERN'adalah execusikan, jika hasilnya adalah falsemaka seluruh ekspresi ! -exec grep -q 'PATTERN'mengevaluasi sebagai truedan nama file printed.

don_crissti
sumber
2
Yang satu memiliki manfaat menjadi standar dan portabel.
Stéphane Chazelas
Namun ada perbedaan dengan GNU karena GNU grep -Ljuga akan menyertakan file yang tidak dapat dibaca dalam daftar.
Stéphane Chazelas
1

Anda menemukan tidak cocok hasil dengan opsi -L

grep -iL shared.php .
prakash
sumber
-1

Saya pikir Anda mencari perintah seperti

find . -type f -execdir grep -q -v shared.php {} \; -print

Opsi ini -qmembuat grepberhenti dan setelah menggunakan -execdirAnda perlu -printmencetak file yang ditemukan.

Ronin Tom
sumber