Cara grep ribuan file dalam direktori untuk ratusan string dalam file


11

Saya mencoba membuat greppernyataan dan itu membunuh saya. Saya juga lelah mendapatkan arguments list too longkesalahan. Saya punya file, sebut saja subset.txt. Ini berisi ratusan baris dengan string spesifik seperti MO43312948. Dalam direktori objek saya, saya memiliki ribuan file dan saya perlu menyalin semua file yang berisi string yang terdaftar di subset.txtdirektori lain.

Saya mencoba memulai dengan ini untuk mengembalikan file yang cocok dari direktori objek.

grep -F "$(subset.txt)" /objects/*

Saya terus mendapatkan `bash: / bin / grep: Daftar argumen terlalu panjang``


6
Mengapa Anda menempatkan "$(subset.txt)"perintah seperti itu? Itu adalah substitusi perintah , yang akan membuat shell Anda mengeksekusi subset.txt (seolah-olah itu adalah perintah atau skrip).
JigglyNaga

Jawaban:


23

Anda dapat melewati direktori sebagai target grepdengan -Rdan file pola input dengan -f:

  -f FILE, --file=FILE
          Obtain patterns from FILE, one per line.  If this option is used
          multiple  times  or  is  combined with the -e (--regexp) option,
          search for all patterns given.  The  empty  file  contains  zero
          patterns, and therefore matches nothing.

   -R, --dereference-recursive
          Read all files under each directory,  recursively.   Follow  all
          symbolic links, unlike -r.

Jadi, Anda mencari:

grep -Ff subset.txt -r objects/

Anda bisa mendapatkan daftar file yang cocok dengan:

grep -Flf subset.txt -r objects/

Jadi, jika daftar terakhir Anda tidak terlalu panjang, Anda bisa melakukannya:

 mv $(grep -Flf subset.txt -r objects/) new_dir/

Jika itu mengembalikan argument list too longkesalahan, gunakan:

grep -Flf subset.txt -r objects/ | xargs -I{} mv {} bar/

Dan jika nama file Anda dapat berisi spasi atau karakter aneh lainnya, gunakan (dengan asumsi GNU grep):

grep -FZlf subset.txt -r objects/ | xargs -0I{} mv {} bar/

Terakhir, jika Anda ingin mengecualikan file biner, gunakan:

grep -IFZlf subset.txt -r objects/ | xargs -0I{} mv {} bar/

... atau untuk menghindari kemungkinan ribuan mvdoa dengan masing-masing satu argumen: ... | xargs -0 mv -t bar/(dengan asumsi Anda mvmendukung -topsi).
David Foerster

11

menggunakan

grep -F -f subset.txt 

untuk memberitahu grep untuk membaca dari subset.txtfile.

Anda dapat menggunakan find untuk menjalankan file.

find . -type f -exec grep -F -f subset.txt {} \;

atau

find . -type f -exec grep -F -f subset.txt {}  +

Setiap keuntungan dari menggunakan findbukannya -rselain itu Anda melakukan penyaringan tambahan?
phk

1
@phk grep -rmencari di symlink ke file biasa, yang mungkin atau mungkin tidak diinginkan (jika mereka menunjuk di dalam pohon yang sama, Anda mencari file yang sama dua kali; jika mereka menunjuk ke luar, Anda mencari file yang mungkin atau mungkin tidak diinginkan).
Gilles 'SO- stop being evil'

Versi modern grepmemiliki opsi untuk mengontrol interaksinya dengan tautan simbolik ( man grepuntuk menentukan spesifikasi sistem saat ini). Rekursif grepakan jauh lebih cepat daripada berjalan secara grepindividual pada setiap file melalui find.
Perry

1
@ Jerry Anda yakin tentang itu? Mengapa? Perhatikan juga bahwa jawaban ini digunakan -exec +, sehingga akan mengelompokkan file dan tidak menjalankan satu grep per file.
terdon

Saya berdiri dikoreksi, saya tidak menyadari perbedaan semantik -exec {} +vs -exec {} \;... Anda belajar sesuatu yang baru setiap hari (saya masih tidak melihat alasan mengapa satu rekursif tunggal greptidak akan lebih cepat daripada beberapa greps berjalan dari findkarena proses pembuatan dan pola parsing overhead tetapi saya tidak memiliki nomor khusus untuk mendukungnya).
Perry

3

Jika Anda ingin mempercepat grep lebih jauh, Anda dapat mengatur lokal di shell Anda sebelum menjalankannya, yaitu gunakan "LC_ALL = c". Ini akan diwarisi menjadi grep dan akan menonaktifkan pemrosesan Unicode bila tidak diperlukan dan dalam beberapa kasus dapat secara dramatis mempercepat grep. Blog hebat yang mendokumentasikan ini dapat ditemukan di http://www.inmotionhosting.com/support/website/ssh/speed-up-grep-searches-with-lc-all . Trik ini juga dapat mempercepat skrip bash shell juga, bukan hanya grep.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.