Bagaimana cara mengetahui file dalam direktori saat ini yang tidak mengandung kata foo
(menggunakan grep
)?
Bagaimana cara mengetahui file dalam direktori saat ini yang tidak mengandung kata foo
(menggunakan grep
)?
Jawaban:
Jika grep Anda memiliki opsi -L
(atau --files-without-match
):
$ grep -L "foo" *
GREP_OPTIONS='--exclude-dir=.svn --exclude-dir=.git'
: ^)
-rL
alih-alih -L
untuk mencocokkan subdirektori
grep -L 'foo' -- *
adalah bahwa perintah yang mengambil opsi lama gunakan --
untuk menunjukkan bahwa tidak ada opsi lagi setelah titik ini.
Lihatlah ack
. Itu .svn
pengecualian untuk Anda secara otomatis, memberi Anda ekspresi reguler Perl, dan merupakan unduhan sederhana dari satu program Perl.
Setara dengan apa yang Anda cari seharusnya, di ack
:
ack -L foo
Anda dapat melakukannya dengan grep saja (tanpa menemukan).
grep -riL "foo" .
Ini adalah penjelasan tentang parameter yang digunakan grep
-L, --files-without-match
each file processed.
-R, -r, --recursive
Recursively search subdirectories listed.
-i, --ignore-case
Perform case insensitive matching.
Jika Anda menggunakan l
(huruf kecil) Anda akan mendapatkan yang sebaliknya (file dengan kecocokan)
-l, --files-with-matches
Only the names of files containing selected lines are written
Perintah berikut memberi saya semua file yang tidak mengandung pola foo
:
find . -not -ipath '.*svn*' -exec grep -H -E -o -c "foo" {} \; | grep 0
grep '0$'
akan cocok dengan file dengan kelipatan 10 baris juga! Anda harus grep ':0$'
di akhir untuk memeriksa ': 0' secara eksplisit di akhir baris. Maka Anda hanya akan mendapatkan file dengan garis nol yang cocok.
Perintah berikut tidak termasuk kebutuhan untuk menemukan untuk menyaring svn
folder dengan menggunakan yang kedua grep
.
grep -rL "foo" ./* | grep -v "\.svn"
Anda benar-benar membutuhkan:
find . -not -ipath '.*svn*' -exec grep -H -E -o -c "foo" {} \; | grep :0\$
Masalah
Saya perlu memperbaiki proyek besar yang menggunakan .phtml
file untuk menulis HTML menggunakan kode PHP sebaris. Saya ingin menggunakan template Moustache sebagai gantinya. Saya ingin menemukan .phtml
gile yang tidak mengandung string new Mustache
karena ini masih perlu ditulis ulang.
Larutan
find . -iname '*.phtml' -exec grep -H -E -o -c 'new Mustache' {} \; | grep :0$ | sed 's/..$//'
Penjelasan
Sebelum pipa:
Temukan
find .
Temukan file secara rekursif, mulai dari direktori ini
-iname '*.phtml'
Nama file harus mengandung .phtml
(thei
make case-insensitive)
-exec 'grep -H -E -o -c 'new Mustache' {}'
Jalankan grep
perintah di setiap jalur yang cocok
Grep
-H
Selalu cetak header nama file dengan jalur output.
-E
Menafsirkan pola sebagai ekspresi reguler yang diperluas (yaitu memaksa grep untuk berperilaku sebagai egrep).
-o
Hanya mencetak bagian garis yang cocok.
-c
Hanya hitungan baris yang dipilih ditulis ke output standar.
Ini akan memberi saya daftar semua jalur file yang diakhiri .phtml
, dengan hitungan berapa kali string new Mustache
muncul di masing-masing jalur tersebut .
$> find . -iname '*.phtml$' -exec 'grep -H -E -o -c 'new Mustache' {}'\;
./app/MyApp/Customer/View/Account/quickcodemanagestore.phtml:0
./app/MyApp/Customer/View/Account/studio.phtml:0
./app/MyApp/Customer/View/Account/orders.phtml:1
./app/MyApp/Customer/View/Account/banking.phtml:1
./app/MyApp/Customer/View/Account/applycomplete.phtml:1
./app/MyApp/Customer/View/Account/catalogue.phtml:1
./app/MyApp/Customer/View/Account/classadd.phtml:0
./app/MyApp/Customer/View/Account/orders-trade.phtml:0
Pipa pertama grep :0$
menyaring daftar ini untuk hanya menyertakan garis yang diakhiri dengan :0
:
$> find . -iname '*.phtml' -exec grep -H -E -o -c 'new Mustache' {} \; | grep :0$
./app/MyApp/Customer/View/Account/quickcodemanagestore.phtml:0
./app/MyApp/Customer/View/Account/studio.phtml:0
./app/MyApp/Customer/View/Account/classadd.phtml:0
./app/MyApp/Customer/View/Account/orders-trade.phtml:0
Pipa kedua sed 's/..$//'
melepas dua karakter terakhir dari setiap baris, hanya menyisakan path file.
$> find . -iname '*.phtml' -exec grep -H -E -o -c 'new Mustache' {} \; | grep :0$ | sed 's/..$//'
./app/MyApp/Customer/View/Account/quickcodemanagestore.phtml
./app/MyApp/Customer/View/Account/studio.phtml
./app/MyApp/Customer/View/Account/classadd.phtml
./app/MyApp/Customer/View/Account/orders-trade.phtml
Grep saya tidak memiliki opsi -L. Saya menemukan solusi untuk mencapai ini.
Gagasannya adalah:
buat perbedaan antara 2 dump file dengan perintah diff.
grep 'foo' *.log | cut -c1-14 | uniq > txt1.txt
grep * *.log | cut -c1-14 | uniq > txt2.txt
diff txt1.txt txt2.txt | grep ">"
diff
antara dua aliran output (saya pikir Anda mengelilingi perintah dengan tanda kurung, dan ada kurung sudut di suatu tempat juga), jika sistem Anda mendukungnya, yang saya kira adalah pertanyaannya, karena itu tidak mendukunggrep -L
find *20161109* -mtime -2|grep -vwE "(TRIGGER)"
Anda dapat menentukan filter di bawah "find" dan string pengecualian di bawah "grep -vwE". Gunakan mtime di bawah find jika Anda juga perlu memfilter waktu yang dimodifikasi.
Seperti yang dikomentari oleh @tukan, ada laporan bug terbuka untuk Ag mengenai -L
/ --files-without-matches
flag:
Karena ada sedikit kemajuan pada laporan bug, -L
opsi yang disebutkan di bawah ini tidak boleh diandalkan , tidak selama bug belum diselesaikan. Gunakan pendekatan berbeda yang disajikan dalam utas ini sebagai gantinya. Mengutip komentar untuk laporan bug [penekanan milik saya]:
Adakah pembaruan tentang ini?
-L
sama sekali mengabaikan kecocokan pada baris pertama file. Sepertinya jika ini tidak akan segera diperbaiki, bendera harus dihapus seluruhnya, karena secara efektif tidak berfungsi seperti yang diiklankan sama sekali .
Sebagai alternatif yang kuat untuk grep
, Anda bisa menggunakan The Silver Searcher - Ag :
Alat pencarian kode yang mirip dengan ack, dengan fokus pada kecepatan.
Melihat man ag
, kami menemukan opsi -L
atau --files-without-matches
:
... OPTIONS ... -L --files-without-matches Only print the names of files that donĀ“t contain matches.
Yakni, untuk mencari file yang tidak cocok secara rekursiffoo
, dari direktori saat ini:
ag -L foo
Untuk hanya mencari direktori saat ini untuk file yang tidak cocok foo
, cukup tentukan --depth=0
untuk rekursi:
ag -L foo --depth 0
-L
bug - github.com/ggreer/the_silver_searcher/issues/238
grep -irnw "filepath" -ve "pattern"
atau
grep -ve "pattern" < file
perintah di atas akan memberi kita hasilnya karena -v menemukan kebalikan dari pola yang dicari
-l
opsi untuk mencetak hanya nama file; tetapi ini masih mencetak nama-nama file yang berisi baris apa pun yang tidak mengandung pola. Saya percaya OP ingin menemukan file yang tidak mengandung garis apa pun yang berisi pola.
Perintah berikut ini dapat membantu Anda untuk memfilter garis yang menyertakan "foo" substring.
cat file | grep -v "foo"
cat
.