Apakah ada cara untuk memaksa find
perintah berhenti tepat setelah menemukan pertandingan pertama?
Apakah ada cara untuk memaksa find
perintah berhenti tepat setelah menemukan pertandingan pertama?
Jawaban:
Dengan GNU atau FreeBSD find
, Anda dapat menggunakan -quit
predikat:
find . ... -print -quit
find
Setara dengan NetBSD :
find . ... -print -exit
Jika semua yang Anda lakukan adalah mencetak nama, dan dengan asumsi nama file tidak mengandung karakter baris baru, Anda bisa melakukannya:
find . ... -print | head -n 1
Itu tidak akan berhenti find
setelah pertandingan pertama, tetapi mungkin, tergantung pada waktu dan buffering pada pertandingan kedua atau (banyak) nanti. Pada dasarnya, find
akan diakhiri dengan SIGPIPE ketika mencoba mengeluarkan sesuatu saat head
sudah tidak ada karena sudah membaca dan menampilkan baris input pertama.
Perhatikan bahwa tidak semua shell akan menunggu find
perintah itu setelah head
kembali. Shell Bourne dan implementasi AT&T ksh
(ketika non-interaktif) dan yash
(hanya jika pipa itu adalah perintah terakhir dalam sebuah skrip) tidak akan, membiarkannya berjalan di latar belakang. Jika Anda lebih suka melihat perilaku itu di shell apa pun, Anda selalu bisa mengubah hal di atas menjadi:
(find . ... -print &) | head -n 1
Jika Anda melakukan lebih dari sekadar mencetak jalur file yang ditemukan, Anda dapat mencoba pendekatan ini:
find . ... -exec sh -c 'printf "%s\n" "$1"; kill "$PPID"' sh {} \;
(ganti printf
dengan apa pun yang Anda lakukan dengan file itu).
Itu memiliki efek samping find
mengembalikan status keluar yang mencerminkan fakta bahwa itu dibunuh.
Sebenarnya, menggunakan sinyal SIGPIPE dan bukannya SIGTERM ( kill -s PIPE
bukan kill
) akan menyebabkan beberapa shell menjadi lebih diam tentang kematian itu (tetapi masih akan mengembalikan status keluar yang tidak nol).
if [[ $(find ... -print -quit) ]]; then ...
Ini hanya menguji apakah menemukan sesuatu yang dicetak sama sekali.
$(…)
bagian dalam tanda kutip jika Anda hanya menggunakan tanda kurung tunggal ( [ … ]
).
[
adalah perintah standar. Ini bukan perintah yang mengerikan tapi cara Bourne-like shells mengurai baris perintah. [[...]]
adalah konstruksi ksh yang memiliki masalah sendiri dalam berbagai shell. Misalnya, hingga saat [[ $(...) ]]
ini tidak akan berfungsi zsh
(Anda perlu [[ -n $(...) ]]
). Kecuali di zsh
, Anda memerlukan tanda kutip di [[ $a = $b ]]
, [[ =~ ]]
memiliki perbedaan yang tidak kompatibel antara implementasi dan bahkan antara versi untuk bash dan beberapa bug di beberapa. Secara pribadi, saya lebih suka [
.
...
? .
find . -name something -print -quit
Menghentikan pencarian setelah pertandingan pertama setelah mencetaknya.
Hentikan pencarian setelah sejumlah yang cocok dan hasil cetak:
find . -name something -print | head -n 5
Cukup mengejutkan - kepala sekarang mengakhiri string setelah 5 pertandingan, meskipun saya tidak tahu bagaimana atau mengapa.
Sangat mudah untuk diuji. Hanya membiarkan menemukan mencari sebuah di akar yang akan menghasilkan ribuan, bahkan mungkin lebih banyak pertandingan saat mengambil setidaknya satu menit atau lebih. Tetapi ketika disalurkan ke "head" "find" akan berakhir setelah jumlah baris yang ditentukan didefinisikan dalam head (head default menunjukkan 10, gunakan "head -n" untuk menentukan baris).
Perhatikan bahwa ini akan berakhir setelah "head -n" mencapai jumlah karakter baris baru yang ditentukan dan karenanya setiap kecocokan yang berisi beberapa karakter baris baru akan dihitung sesuai.
Untuk tujuan hiburan, inilah generator pencari malas di Bash. Contoh ini menghasilkan cincin di atas file di direktori saat ini. Bacalah sebanyak yang Anda inginkan kill %+
(mungkin hanya 1)
#!/usr/bin/env bash
unset -v files n
trap 'kill "$x_PID"' EXIT
coproc x while :; do
find . -type f -maxdepth 1 -exec sh -c "$(</dev/fd/3)" _ {} +
done 4<&0 <<\EOF 3<&0 <&4-
for x; do
read -r _
printf '%s\0' "$x"
done
EOF
while
echo >&${x[1]}
IFS= read -rd '' -u "$x" 'files[n++]'
do
printf '%q ' "${files[@]}"
echo
sleep .2
done
grep juga kembali jika digunakan dengan flag -m
, begitu juga dengan
find stuff | grep -m1 .
itu akan kembali setelah baris pertama dicetak oleh find.
Perbedaan antara ini dan find stuff -print -quit | head -1
adalah bahwa jika pencarian grep cukup cepat mungkin tidak dapat menghentikan proses dalam waktu (tidak terlalu penting meskipun), sedangkan jika pencarian panjang itu akan menghemat menemukan untuk mencetak banyak yang tidak diperlukan garis.
ini malah berfungsi dengan busybox find, walaupun karena busybox grep juga memilikinya -m
tidak terlalu diperlukan
find /tmp/stuff -exec "sh" "-c" "eval 'echo {}; { kill \$PPID; }'" \;
ini akan memuntahkan pesan tentang proses find setelah menerima sinyal sigterm (biasanya), tetapi output ini milik shell yang sedang berjalan, bukan perintah find sehingga tidak mengacaukan dengan output perintah, artinya pipa atau pengalihan akan menampilkan hanya baris cocok dengan find.