Saya tidak yakin:
grep -r -i 'the brown dog' /*
benar-benar yang Anda maksudkan. Itu berarti grep secara rekursif di semua file dan dirs non-tersembunyi /
(tapi masih mencari di dalam file dan dirs tersembunyi di dalamnya).
Anggap Anda maksud:
grep -r -i 'the brown dog' /
Beberapa hal yang perlu diperhatikan:
- Tidak semua
grep
implementasi mendukung -r
. Dan di antara mereka yang melakukannya, perilaku berbeda: beberapa mengikuti symlink ke direktori ketika melintasi pohon direktori (yang berarti Anda mungkin berakhir mencari beberapa kali dalam file yang sama atau bahkan berjalan dalam loop tak terbatas), beberapa tidak akan. Beberapa akan mencari di dalam file perangkat (dan itu akan membutuhkan beberapa waktu /dev/zero
misalnya) atau pipa atau file biner ..., beberapa tidak.
- Ini efisien karena
grep
mulai mencari ke dalam file begitu menemukan mereka. Tetapi sementara itu terlihat dalam sebuah file, itu tidak lagi mencari lebih banyak file untuk dicari (yang mungkin sama baiknya dalam kebanyakan kasus)
Anda:
find / -type f -exec grep -i 'the brown dog' {} \;
(menghapus -r
yang tidak masuk akal di sini) sangat tidak efisien karena Anda menjalankan satu grep
per file. ;
seharusnya hanya digunakan untuk perintah yang hanya menerima satu argumen. Terlebih lagi di sini, karena grep
hanya terlihat dalam satu file, itu tidak akan mencetak nama file, sehingga Anda tidak akan tahu di mana pertandingannya.
Anda tidak mencari di dalam file perangkat, pipa, symlink ..., Anda tidak mengikuti symlink, tetapi Anda masih berpotensi mencari hal-hal seperti di dalamnya /proc/mem
.
find / -type f -exec grep -i 'the brown dog' {} +
akan jauh lebih baik karena grep
perintah sesedikit mungkin akan dijalankan. Anda akan mendapatkan nama file kecuali proses terakhir hanya memiliki satu file. Untuk itu lebih baik menggunakan:
find / -type f -exec grep -i 'the brown dog' /dev/null {} +
atau dengan GNU grep
:
find / -type f -exec grep -Hi 'the brown dog' {} +
Perhatikan bahwa grep
tidak akan dimulai sampai find
menemukan cukup file untuk dikunyah, sehingga akan ada beberapa penundaan awal. Dan find
tidak akan melanjutkan mencari lebih banyak file sampai sebelumnya grep
telah kembali. Mengalokasikan dan melewati daftar file besar memiliki beberapa dampak (mungkin dapat diabaikan), jadi semuanya mungkin akan kurang efisien daripada grep -r
yang tidak mengikuti symlink atau melihat ke dalam perangkat.
Dengan alat GNU:
find / -type f -print0 | xargs -r0 grep -Hi 'the brown dog'
Seperti di atas, beberapa grep
contoh mungkin akan dijalankan, tetapi find
akan terus mencari lebih banyak file sementara grep
doa pertama mencari di dalam batch pertama. Itu mungkin atau mungkin tidak menguntungkan. Misalnya, dengan data yang disimpan pada hard drive rotasi, find
dan grep
mengakses data yang disimpan di lokasi yang berbeda pada disk akan memperlambat throughput disk dengan menyebabkan kepala disk bergerak terus-menerus. Dalam pengaturan RAID (di mana find
dan grep
dapat mengakses disk yang berbeda) atau pada SSD, yang mungkin membuat perbedaan positif.
Dalam pengaturan RAID, menjalankan beberapa pemanggilan serentak grep
juga dapat meningkatkan banyak hal. Masih dengan alat GNU pada penyimpanan RAID1 dengan 3 disk,
find / -type f -print0 | xargs -r0 -P2 grep -Hi 'the brown dog'
dapat meningkatkan kinerja secara signifikan. Namun perlu dicatat bahwa yang kedua grep
hanya akan dimulai setelah file yang cukup telah ditemukan untuk mengisi grep
perintah pertama . Anda dapat menambahkan -n
opsi agar hal xargs
itu terjadi lebih cepat (dan memberikan lebih sedikit file per grep
permintaan).
Juga perhatikan bahwa jika Anda mengarahkan xargs
output ke apa pun selain perangkat terminal, maka greps
s akan mulai buffering output mereka yang berarti bahwa output dari mereka grep
mungkin akan disisipkan secara tidak benar. Anda harus menggunakan stdbuf -oL
(jika tersedia seperti pada GNU atau FreeBSD) pada mereka untuk mengatasinya (Anda mungkin masih memiliki masalah dengan garis yang sangat panjang (biasanya> 4KiB)) atau minta masing-masing menuliskan output mereka dalam file terpisah dan menggabungkannya semua pada akhirnya.
Di sini, string yang Anda cari sudah diperbaiki (bukan regexp) jadi menggunakan -F
opsi mungkin akan membuat perbedaan (tidak mungkin karena grep
implementasi tahu cara mengoptimalkannya).
Hal lain yang dapat membuat perbedaan besar adalah memperbaiki lokal ke C jika Anda berada di lokal multi-byte:
find / -type f -print0 | LC_ALL=C xargs -r0 -P2 grep -Hi 'the brown dog'
Untuk menghindari mencari ke dalam /proc
, /sys
..., gunakan -xdev
dan tentukan sistem file yang ingin Anda cari:
LC_ALL=C find / /home -xdev -type f -exec grep -i 'the brown dog' /dev/null {} +
Atau pangkas jalur yang ingin Anda kecualikan secara eksplisit:
LC_ALL=C find / \( -path /dev -o -path /proc -o -path /sys \) -prune -o \
-type f -exec grep -i 'the brown dog' /dev/null {} +