Ketika saya ingin mencari seluruh pohon untuk beberapa konten, saya menggunakan
find . -type f -print0 | xargs -0 grep <search_string>
Apakah ada cara yang lebih baik untuk melakukan ini dalam hal kinerja atau singkatnya?
Ketika saya ingin mencari seluruh pohon untuk beberapa konten, saya menggunakan
find . -type f -print0 | xargs -0 grep <search_string>
Apakah ada cara yang lebih baik untuk melakukan ini dalam hal kinerja atau singkatnya?
Jawaban:
Periksa apakah opsi grep
dukungan Anda -r
(untuk pengulangan ):
grep -r <search_string> .
--exclude-dir
untuk mengatasi kinerja dan kami memiliki seorang pemenang!
grep
pada distro FreeBSD dan Linux terbaru mendukungnya. Dan mengapa --exclude-dir
? Tidakkah Anda meminta untuk mencari seluruh pohon ?
--exclude-dir
sebenarnya berguna dalam kasus penggunaan saya (karena bagian dari subtree besar, tetapi tidak berguna) dan saya memang bertanya tentang kinerja ... tetapi Anda benar, itu tidak perlu.
--exclude-dir
eksklusif untuk GNU grep
. (-:
Jawaban sub optimal: Alih-alih menyalurkan output find
ke grep
, Anda bisa menjalankan
find . -type f -exec grep 'research' {} '+'
dan voila, satu perintah, bukan dua!
penjelasan:
find . -type f
temukan semua file biasa di dalamnya.
-exec grep 'research'
grep 'penelitian'
{}
dalam nama file yang ditemukan
'+'
gunakan satu perintah per semua nama file, tidak satu kali per nama file.
Nb: dengan ';'
itu akan menjadi sekali per nama file.
Selain itu, jika Anda menggunakannya untuk memproses kode sumber, Anda dapat melihat ack
, yang dibuat untuk mencari bit kode dengan mudah.
Edit:
Anda dapat memperluas penelitian itu sedikit. Pertama, Anda dapat menggunakan -name ''
sakelar find
untuk mencari file dengan pola penamaan yang spesifik.
Contohnya :
hanya file yang terkait dengan log: -name '*.log'
hanya file yang sesuai dengan header c, tetapi Anda tidak bisa menggunakan huruf besar atau kecil untuk ekstensi nama file Anda: -iname *.c
Nb: suka untuk grep
dan ack
, -i
sakelar berarti case-sensitive dalam hal ini.
Dalam hal ini, grep akan ditampilkan tanpa warna dan tanpa nomor garis.
Anda dapat mengubah itu dengan --color
dan -n
switch (masing-masing warna dan nomor baris dalam file).
Pada akhirnya, Anda dapat memiliki sesuatu seperti:
find . -name '*.log' -type f -exec grep --color -n 'pattern' {} '+'
contohnya
$ find . -name '*.c' -type f -exec grep -n 'hello' {} '+'
./test2/target.c:1:hello
-name '*.log'
Ini lebih cepat.
Jika Anda ingin rekursi menjadi subdirektori:
grep -R 'pattern' .
The -R
pilihan adalah bukan pilihan yang standar, tetapi didukung oleh paling umum grep
implementasi.
-r
alih-alih -R
untuk melewatkan symlink ketika GNU grep terkait
grep
implementasi GNU saat ini menangkap rekursi, saya pikir. Kalau tidak, itu tergantung pada apa yang Anda maksud dengan "tree".
grep
harus dilakukan oleh alat . Jika pengguna memiliki loop tautan simbolis dalam struktur direktori mereka, well, itu masalah pengguna :-)
/sys/devices/cpu/subsystem/devices/cpu/subsystem/devices/cpu/...
(-XI seperti alat menjaga saya (kecuali mereka memberikan sihir aneh yang mereka sebut "AI"). (-;
Seperti disebutkan di atas -r
atau -R
(tergantung pada penanganan symlink yang diinginkan) adalah opsi cepat.
Namun -d <action>
bisa bermanfaat sesekali.
Yang menyenangkan -d
adalah perintah lewati, yang membungkam "grep: directory_name: Is a direktori" ketika Anda hanya ingin memindai level saat ini.
$ grep foo *
grep: q2: Is a directory
grep: rt: Is a directory
$ grep -d skip foo *
$
dan tentu saja:
$ grep -d recurse foo *
(list of results that don't exist because the word foo isn't in our source code
and I wouldn't publish it anyway).
$
The -d skip
pilihan adalah benar-benar berguna dalam script lain sehingga Anda tidak perlu 2> /dev/null
. :)
Jika Anda berurusan dengan banyak file, grep berjalan lebih cepat jika Anda memangkas file yang perlu dicari alih-alih mengambil semua file dalam subfolder.
Saya terkadang menggunakan format ini:
grep "primary" `find . | grep cpp$`
Temukan semua file dalam subfolder .
yang berakhir di cpp
. Kemudian ambil file-file itu untuk "primer".
Jika mau, Anda dapat terus memipatkan hasil tersebut ke panggilan grep lebih lanjut:
grep "primary" `find . | grep cpp$` | grep -v "ignoreThis" | grep -i "caseInsensitiveGrep"