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?