GNU/Linux >> Belajar Linux >  >> Linux

Batasi Cari Keluaran Dan Hindari Sinyal 13?

Saya memiliki direktori dengan ~1 juta file dan perlu mencari pola tertentu. Saya tahu bagaimana melakukannya untuk semua file:

find /path/ -exec grep -H -m 1 'pattern' {} ;

Output penuh tidak diinginkan (terlalu lambat). Beberapa hit pertama tidak apa-apa, jadi saya mencoba membatasi jumlah baris:

find /path/ -exec grep -H -m 1 'pattern' {} ; | head -n 5

Ini menghasilkan 5 baris diikuti oleh

find: `grep' terminated by signal 13

dan find terus bekerja. Ini dijelaskan dengan baik di sini. Saya mencoba quit tindakan:

find /path/ -exec grep -H -m 1 'pattern' {} ; -quit

Ini hanya menampilkan kecocokan pertama.

Apakah mungkin membatasi keluaran find dengan jumlah hasil tertentu (seperti memberikan argumen untuk quit mirip dengan head -n )?

Jawaban yang Diterima:

Karena Anda sudah menggunakan ekstensi GNU (-quit , -H , -m1 ), Anda sebaiknya menggunakan GNU grep -r opsi, bersama dengan --line-buffered jadi ini menampilkan kecocokan segera setelah ditemukan, jadi kemungkinan besar SIGPIPE akan dibunuh segera setelah menulis baris ke-6:

grep -rHm1 --line-buffered pattern /path | head -n 5

Dengan find , Anda mungkin perlu melakukan sesuatu seperti:

find /path -type f -exec sh -c '
  grep -Hm1 --line-buffered pattern "[email protected]"
  [ "$(kill -l "$?")" = PIPE ] && kill -s PIPE "$PPID"
  ' sh {} + | head -n 5

Yaitu, bungkus grep di sh (Anda masih ingin menjalankan sedikit grep pemanggilan sebanyak mungkin, maka {} + ), dan memiliki sh bunuh induknya (find ) ketika grep meninggal karena SIGPIPE.

Pendekatan lain bisa menggunakan xargs sebagai alternatif untuk -exec {} + . xargs langsung keluar saat perintah yang dihasilkannya mati karena sinyal jadi di:

 find . -type f -print0 |
   xargs -r0 grep -Hm1 --line-buffered pattern |
   head -n 5

(-r dan -0 menjadi ekstensi GNU). Segera setelah grep menulis ke pipa yang rusak, keduanya grep dan xargs akan keluar dan find akan keluar dengan sendirinya saat berikutnya ia mencetak sesuatu setelah itu. Menjalankan find di bawah stdbuf -oL mungkin bisa mewujudkannya lebih cepat.

Versi POSIX dapat berupa:

trap - PIPE # restore default SIGPIPE handler in case it was disabled
RE=pattern find /path -type f -exec sh -c '
  for file do
    awk '''
      $0 ~ ENVIRON["RE"] {
        print FILENAME ": " $0
        exit
      }''' < "$file"
    if [ "$(kill -l "$?")" = PIPE ]; then
      kill -s PIPE "$PPID"
      exit
    fi
  done' sh {} + | head -n 5

Sangat tidak efisien karena menjalankan beberapa perintah untuk setiap file.

Terkait:Ubuntu – Bagaimana cara mengunci kecepatan kipas untuk amd gpu di Ubuntu 20.04?
Linux
  1. Bagaimana Menemukan/grep Apa Antara String1 Dan String2?

  2. Potong / Grep Dan Df -h?

  3. Grep Dan Ekor -f?

  1. Gunakan grep untuk menemukan konten dalam file dan memindahkannya jika cocok

  2. Menggunakan grep dan sed untuk mencari dan mengganti string

  3. Bagaimana cara Menggabungkan find dan grep untuk pencarian yang kompleks? ( GNU/linux, temukan, grep )

  1. Output Ke Stdout Dan Pada Saat Yang Sama Grep Ke File?

  2. Bagaimana cara membatasi keluaran ls untuk hanya menampilkan nama file, tanggal dan ukuran?

  3. Cara grep keluaran ps dengan header