GNU/Linux >> Belajar Linux >  >> Linux

Grep Rekursif Vs Temukan / -type F -exec Grep {}; Mana yang Lebih Efisien/Lebih Cepat?

Mana yang lebih efisien untuk menemukan file mana di seluruh sistem file yang berisi string:grep rekursif atau temukan dengan grep dalam pernyataan exec? Saya berasumsi find akan lebih efisien karena Anda setidaknya dapat melakukan beberapa pemfilteran jika Anda mengetahui ekstensi file atau regex yang cocok dengan nama file, tetapi ketika Anda hanya tahu -type f mana yang lebih baik? grep GNU 2.6.3; temukan (GNU findutils) 4.4.2

Contoh:

grep -r -i 'the brown dog' /

find / -type f -exec grep -i 'the brown dog' {} ;

Jawaban yang Diterima:

Saya tidak yakin:

grep -r -i 'the brown dog' /*

benar-benar apa yang Anda maksud. Itu berarti grep secara rekursif di semua file dan direktori yang tidak disembunyikan di / (tetapi masih melihat ke dalam file dan direktori tersembunyi di dalamnya).

Dengan asumsi yang 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, perilakunya berbeda:beberapa mengikuti symlink ke direktori saat melintasi pohon direktori (yang berarti Anda mungkin akhirnya mencari beberapa kali dalam file yang sama atau bahkan berjalan dalam infinite loop), beberapa tidak. Beberapa akan melihat ke dalam file perangkat (dan akan memakan waktu cukup lama di /dev/zero misalnya) atau pipa atau file biner…, beberapa tidak.
  • Efisien seperti grep mulai mencari ke dalam file segera setelah menemukannya. Namun saat mencari dalam sebuah file, ia tidak lagi mencari lebih banyak file untuk ditelusuri (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 berkas. ; hanya boleh digunakan untuk perintah yang hanya menerima satu argumen. Apalagi di sini, karena grep terlihat hanya dalam satu file, tidak akan mencetak nama file, sehingga Anda tidak akan tahu di mana kecocokannya.

Anda tidak melihat ke dalam file perangkat, pipa, symlink..., Anda tidak mengikuti symlink, tetapi Anda masih berpotensi melihat ke dalam hal-hal seperti /proc/mem .

find / -type f -exec grep -i 'the brown dog' {} +

akan jauh lebih baik karena sedikit grep perintah 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 telah menemukan cukup file untuk dikunyah, jadi akan ada beberapa penundaan awal. Dan find tidak akan melanjutkan mencari lebih banyak file sampai grep sebelumnya telah kembali. Mengalokasikan dan meneruskan daftar file besar memiliki beberapa dampak (mungkin dapat diabaikan), jadi secara keseluruhan mungkin akan kurang efisien daripada grep -r yang tidak mengikuti symlink atau melihat ke dalam perangkat.

Terkait:Bagaimana cara kerja ${0##*/} dan ${0%/*}?

Dengan alat GNU:

find / -type f -print0 | xargs -r0 grep -Hi 'the brown dog'

Seperti di atas, sedikitnya grep instance mungkin akan dijalankan, tetapi find akan terus mencari lebih banyak file sementara grep pertama doa sedang melihat ke dalam batch pertama. Itu mungkin atau mungkin bukan keuntungan. 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 penyiapan RAID, menjalankan beberapa bersamaan grep doa mungkin juga memperbaiki keadaan. 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 perhatikan bahwa grep second kedua hanya akan dimulai setelah cukup banyak file ditemukan untuk mengisi grep pertama memerintah. Anda dapat menambahkan -n pilihan untuk xargs agar itu terjadi lebih cepat (dan meneruskan lebih sedikit file per grep doa).

Perhatikan juga bahwa jika Anda mengarahkan xargs output ke apa pun kecuali perangkat terminal, lalu greps s akan mulai menyangga output mereka yang berarti bahwa output dari grep . tersebut s mungkin akan disisipkan secara tidak benar. Anda harus menggunakan stdbuf -oL (jika tersedia seperti di GNU atau FreeBSD) pada mereka untuk mengatasinya (Anda mungkin masih memiliki masalah dengan garis yang sangat panjang (biasanya>4KiB)) atau minta masing-masing menulis output mereka dalam file terpisah dan menggabungkan semuanya pada akhirnya.

Di sini, string yang Anda cari sudah diperbaiki (bukan regexp) jadi gunakan -F opsi mungkin membuat perbedaan (tidak mungkin sebagai grep implementasi sudah tahu cara mengoptimalkannya).

Hal lain yang dapat membuat perbedaan besar adalah memperbaiki lokal ke C jika Anda menggunakan lokal multi-byte:

find / -type f -print0 | LC_ALL=C xargs -r0 -P2 grep -Hi 'the brown dog'

Untuk menghindari melihat 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 {} +

Linux
  1. Mendapatkan Opsi -exec Di Temukan Untuk Bekerja?

  2. Bagaimana Menemukan Banyak String Dalam File??

  3. temukan -exec fungsi shell di Linux?

  1. Temukan Kecualikan Direktori?

  2. Menemukan direktori di Terminal Linux

  3. Cara grep baris yang memiliki lebih dari jumlah karakter khusus tertentu

  1. Temukan -exec + Vs Temukan | Xargs:Yang Mana Yang Harus Dipilih?

  2. Mencetak Nama File Bersama Dengan Hasil Grep Di Temukan -exec?

  3. Keluar Dari Temukan Jika -exec Gagal?