Unix 'grep' untuk string di dalam semua file gzip di semua subdirektori

8

Bagaimana cara saya menerima string secara rekursif melalui semua .gzfile di semua direktori dan subdirektori?

Peter Mortensen
sumber

Jawaban:

13

@Steve Weet hampir tiba. Penggunaan / dev / null sebagai argumen tambahan adalah cara yang bagus untuk memaksa nama file ditampilkan (saya akan ingat itu, terima kasih Steve) tetapi masih menjalankan exec untuk setiap file yang ditemukan - overhead yang besar.

Anda ingin menjalankan zgrep sesering mungkin, dapatkan hasil maksimal dari setiap eksekusi:

find . -iname '*.gz' -print0 | xargs -0 zgrep PATTERN

xargsakan menyediakan sebanyak mungkin args (nama file) ke zgrep, dan berulang kali jalankan sampai ia menggunakan semua file yang disediakan oleh findperintah. Menggunakan -print0dan -0opsi memungkinkan untuk bekerja jika ada spasi di salah satu file atau nama direktori.

Di Mac OS X, Anda dapat mencapai efek yang sama tanpa xargs:

find . -iname '*.gz' -exec zgrep PATTERN {} +
Stephen P
sumber
+1 Sangat bagus. Saya tidak menyadari bahwa xargs melewati lebih dari satu argumen. Sebagian besar baris perintah * nix saya adalah 20 tahun dan saya tidak berpikir xarg melakukannya 20 tahun lalu.
Steve Weet
Ternyata temuan di os / x berperilaku sama seperti xargs
Steve Weet
1
Lihat komentar saya untuk jawaban Steve Weet mengenai akhiran '+' ke -exec.
Daniel Andersson
Gunakan -Huntuk selalu menampilkan nama file dengan baris yang cocok, setidaknya di GNU grep.
Daniel Andersson
1
$ zgrep --help
Usage: /bin/zgrep [OPTION]... [-e] PATTERN [FILE]...
Look for instances of PATTERN in the input FILEs, using their
uncompressed contents if they are compressed.

Jadi sesuatu seperti itu

find . -iname "*.gz" -exec zgrep PATTERN {} \
aioobe
sumber
-Exec akan menelurkan instance baru zgrep untuk setiap file yang diulanginya sehingga mencegah Anda melihat nama file. Akan lebih baik digunakan zgrep -runtuk pergi melalui pohon atau jika -r tidak bekerja, pipa output dari xargs zgrep
temuan
Saya mendapatkan /bin/zgrep: -r: option not supportedsistem ubuntu saya yang baru diinstal.
aioobe
Anda bisa menggunakannya xargssebagai gantinya.
Noufal Ibrahim
Lihat komentar saya untuk jawaban Steve Weet mengenai akhiran '+' ke -exec.
Daniel Andersson
1

@aioobe hampir sampai. Perintah akan melakukan pekerjaan tetapi tidak akan memberi tahu Anda nama file

Yang berikut juga harus memberi tahu Anda nama file:

find . -iname "*.gz" -exec zgrep PATTERN {} /dev/null \;

Penambahan /dev/nullakan memastikan bahwa zgrep melihat dua nama file sehingga akan menunjukkan kepada Anda nama file jika menemukan string

EDIT

Penelitian lebih lanjut mengungkapkan bahwa untuk mesin saya (OS / X) -execargumen untuk menemukan akan menambahkan sebanyak mungkin nama file (mirip dengan cara xargsberperilaku).

Steve Weet
sumber
Itu cukup keren, saya tidak tahu tentang OSX -exec- saya semua tentang portabilitas jadi saya tidak akan menggunakannya dalam skrip, tetapi bagus untuk command prompt.
Untuk versi lain dari pencarian, gunakan '+' alih-alih '\;' untuk mengakhiri pernyataan exec akan melakukan hal yang sama seperti OSX, menurut cerita di utas ini, tidak secara default. Lihat entri manual untuk '-exec command {} +'. Ini tidak berlaku untuk semua versi find, tetapi sebagian besar versi modern (misalnya dalam distro berbasis Debian).
Daniel Andersson
Gunakan -Huntuk selalu menampilkan nama file dengan baris yang cocok, setidaknya di GNU grep, alih-alih /dev/nullperetasan.
Daniel Andersson
0

Berikut ini adalah suguhan di zsh

for archive in **/*.gz; do
    echo "[${archive}] "
    gzip -dc ${archive} | grep -n "String"
done

Hal ini juga dapat bekerja di bash, ksh, dll ...

Johnsyweb
sumber