Saya memiliki direktori dengan cca 26 000 file dan saya perlu membaca semua file ini. Masalahnya adalah, saya membutuhkannya secepat mungkin, jadi tidak ideal untuk membuat skrip di mana grep akan mengambil nama satu file dari perintah find dan menulis kecocokan ke file. Sebelum masalah "daftar argumen terlalu panjang" butuh waktu 2 menit untuk memahami semua file ini. Ada ide bagaimana melakukannya? sunting: ada skrip yang membuat file baru setiap saat, jadi tidak mungkin untuk meletakkan semua file ke direktori yang berbeda.
files
grep
performance
pengguna2778979
sumber
sumber
find
denganxargs
ataugrep -R
Jawaban:
Dengan
find
:(
-type f
adalah hanya mencari di file biasa (juga mengecualikan symlink bahkan jika mereka menunjuk ke file biasa). Jika Anda ingin mencari di semua jenis file kecuali direktori (tapi waspadalah ada beberapa jenis file seperti fifos atau / dev / zero yang Anda umumnya tidak ingin membaca), ganti-type f
dengan GNU-spesifik! -xtype d
(-xtype d
cocok untuk file-file dari direktori tipe setelah resolusi symlink)).Dengan GNU
grep
:(tetapi berhati-hatilah bahwa kecuali Anda memiliki versi terbaru GNU grep, itu akan mengikuti symlink ketika turun ke direktori). File tidak biasa tidak akan dicari kecuali Anda menambahkan
-D read
opsi. Versi terbaru dari GNUgrep
masih tidak akan mencari di dalam symlink.Versi GNU yang sangat lama
find
tidak mendukung{} +
sintaks standar , tetapi di sana Anda dapat menggunakan non-standar:Pertunjukan cenderung terikat I / O. Itu adalah waktu untuk melakukan pencarian akan menjadi waktu yang dibutuhkan untuk membaca semua data dari penyimpanan.
Jika data pada array disk yang redundan, membaca beberapa file sekaligus dapat meningkatkan kinerja (dan sebaliknya dapat menurunkannya). Jika kinerjanya tidak terikat I / O (karena misalnya semua data ada dalam cache), dan Anda memiliki banyak CPU, lakukan bersamaan
greps
dapat juga membantu. Anda dapat melakukannya dengan GNUxargs
's-P
pilihan.Misalnya, jika data pada array RAID1 dengan 3 drive, atau jika data dalam cache dan Anda memiliki 3 CPU yang waktunya luang:
(di sini menggunakan
-n1000
untuk menelurkan yang barugrep
setiap 1000 file, hingga 3 berjalan secara paralel pada suatu waktu).Namun perhatikan bahwa jika output
grep
diarahkan, Anda akan berakhir dengan output yang disisipkan sangat buruk dari 3grep
proses, dalam hal ini Anda mungkin ingin menjalankannya sebagai:(pada sistem GNU atau FreeBSD baru-baru ini) atau gunakan
--line-buffered
opsi GNUgrep
.Jika
pattern
string tetap, menambahkan-F
opsi dapat memperbaiki masalah.Jika itu bukan data karakter multi-byte, atau jika untuk pencocokan pola itu, tidak masalah apakah data tersebut karakter multi-byte atau tidak, maka:
dapat meningkatkan kinerja secara signifikan.
Jika Anda akhirnya sering melakukan pencarian seperti itu, maka Anda mungkin ingin mengindeks data Anda menggunakan salah satu dari banyak mesin pencari di luar sana.
sumber
26000 file dalam satu direktori banyak untuk sebagian besar sistem file. Kemungkinan sebagian besar waktu diambil untuk membaca direktori besar ini. Pertimbangkan membaginya menjadi direktori yang lebih kecil dengan masing-masing hanya beberapa ratus file.
Menelepon
find
tidak dapat menjelaskan kinerja yang buruk kecuali Anda salah melakukannya. Ini cara cepat melintasi direktori, dan memastikan bahwa Anda tidak mengambil risiko mencoba mengeksekusi baris perintah yang terlalu lama. Pastikan bahwa Anda menggunakan-exec grep PATTERN {} +
, yang mengemas file sebanyak mungkin per permintaan doa, dan tidak-exec grep PATTERN {} \;
, yang mengeksekusigrep
sekali per file: mengeksekusi perintah sekali per file cenderung jauh lebih lambat.sumber
Jika Anda perlu grep SEMUA file beberapa kali (seperti yang Anda katakan, menjalankan skrip) Saya sarankan melihat ke ram ram, salin semua file di sana dan kemudian grep file beberapa kali, ini akan mempercepat pencarian Anda dengan faktor setidaknya 100x.
Anda hanya perlu ram yang cukup. Lain, Anda harus melihat ke dalam mengindeks file, misalnya. ke dalam lucene atau basis data nosql dan kemudian menjalankan query atas itu.
sumber
grep
. Ada juga intinya bahwa: "ada skrip yang membuat file baru setiap saat, jadi tidak mungkin untuk meletakkan semua file ke direktori yang berbeda."Semua file dalam direktori
dengan rekursif
sumber
.
bukan*
).*
akan mengecualikan file dot (meskipun dengan -R, bukan yang ada di direktori berulang). -R sebagai lawan dari -r mengikuti symlink bahkan dengan versi terbaru dari GNU grep. Anda juga akan memiliki masalah dengan file di direktori saat ini yang namanya dimulai dengan-