Bagaimana cara mendeteksi apakah “menemukan” menemukan kecocokan?

16

Apakah ada cara idiomatis untuk mendeteksi apakah "menemukan" menemukan kecocokan? Saya sedang menggunakan

COUNT=`find ... | wc -l`
if [ "$COUNT" -gt 0 ]; then

tetapi ini tampaknya sedikit tidak langsung bagi saya. Juga, saya ingin berhenti mencari setelah menemukan kecocokan, sehingga tidak membuang waktu dan usaha. Saya hanya perlu tahu apakah ada file yang cocok atau tidak.

Pembaruan: Saya membuat kesalahan dengan menulis pertanyaan saya tanpa kode di depan saya: Saya menggunakan wc -ldalam kasus yang berbeda, di mana saya perlu mengetahui jumlah total file yang ditemukan. Dalam kasus di mana saya hanya menguji apakah ada kecocokan, saya menggunakan if [ -z $(find …) ].

Chris Page
sumber

Jawaban:

17

Jika Anda tahu Anda memiliki GNU find, gunakan -quit untuk menghentikannya setelah pertandingan pertama.

Mudah dibawa, pipakan output findke head -n 1. Dengan cara itu findakan mati karena pipa yang rusak setelah beberapa pertandingan (ketika itu diisi headbuffer input).

Either way, Anda tidak perlu wcmenguji apakah string kosong, shell dapat melakukannya sendiri.

if [ -n "$(find … | head -n 1)" ]; then …
Gilles 'SANGAT berhenti menjadi jahat'
sumber
Menarik ... Saya pikir -nhanya berlaku untuk variabel 'didefinisikan' ($ abc, $ xyz, dll), tapi saya kira $ (...) adalah variabel temp 'didefinisikan' .. +1 ... (dan saya hanya baca baru-baru ini bahwa menggunakan -nberisiko, kecuali Anda yakin bahwa variabel belum dideklarasikan dan 'tidak digunakan) ... tetapi temp tidak akan memiliki kemungkinan ini ... yaitu. tidak diinisialisasi vs. kosong
Peter.O
2
@ Fred: Sebaliknya, -nmenguji apakah string kosong, itu tidak ada hubungannya dengan variabel. Apa yang Anda baca mungkin mengatakan bahwa menggunakan -ntidak menguji apakah variabel didefinisikan: -n "$foo"salah jika foodidefinisikan tetapi kosong, dan menampilkan pesan kesalahan di bawah set -u. [ -n "${foo+1}" ]andal menguji apakah foodiatur, tetapi memperlakukan variabel kosong dan tidak disetel secara identik biasanya merupakan ide yang baik:, [ -n "${foo:+1}" ]atau hanya [ -n "$foo" ]jika Anda tidak khawatir set -u.
Gilles 'SO- stop being evil'
Terima kasih! Saya tidak memiliki -quittersedia, tetapi pipa untuk head -n 1bekerja (seperti halnya head -c 1, yang berhenti bahkan lebih awal, tetapi mungkin dengan manfaat yang dapat diabaikan). Juga, saya membuat kesalahan dengan menulis pertanyaan saya tanpa kode di depan saya: Saya menggunakan wc -ldalam kasus yang berbeda, di mana saya perlu mengetahui jumlah total file yang ditemukan. Dalam kasus di mana saya hanya menguji apakah ada kecocokan, saya menggunakan if [ -z `find … ` ].
Chris Page
6

Anda dapat menggunakan -quittindakan untuk berhenti setelah pertandingan pertama. Anda mungkin ingin menggabungkannya dengan tindakan lain (seperti -print) atau Anda tidak akan dapat mengetahui apakah itu menemukan sesuatu.

Misalnya, find ... -print -quitakan mencetak jalur file yang cocok pertama dan kemudian keluar. Atau, Anda dapat menggunakan -printf 1 -quituntuk mencetak 1 jika ada kecocokan dan tidak ada jika tidak ada.

findStatus keluar mencerminkan apakah ada kesalahan saat mencari, dan bukan apakah itu menemukan sesuatu, jadi Anda harus memeriksa hasilnya untuk melihat apakah ada kecocokan.

cjm
sumber
-quitadalah ekstensi GNU. Ini tidak akan bekerja pada sistem yang menggunakan implementasi find (1) lainnya, seperti OS X, BSD, dan mungkin sebagian besar Unices komersial.
Warren Young
Terima kasih, itu berguna untuk mengetahui jika saya menggunakan sistem lain. Sayangnya, tidak ada -quit atau -printf tersedia pada saya (Mac OS X).
Chris Page
4

Keluar 0 mudah dengan menemukan, keluar> 0 lebih sulit karena biasanya hanya terjadi dengan kesalahan. Namun kita dapat mewujudkannya:

if find -type f -exec false {} +
then
  echo 'nothing found'
else
  echo 'something found'
fi

Perhatikan bahwa solusi ini lebih performan daripada menggunakan subkulit; mengeksekusi false tentu saja lebih cepat daripada mengeksekusi bahkan Dash:

$ cat alfa.sh bravo.sh charlie.sh delta.sh
find -name non-existing-file -exec false {} +
find -name existing-file -exec false {} +
[ "$(find -name non-existing-file)" ]
[ "$(find -name existing-file)" ]

$ strace dash alfa.sh | wc -l
807

$ strace dash bravo.sh | wc -l
1141

$ strace dash charlie.sh | wc -l
1184

$ strace dash delta.sh | wc -l
1194
Steven Penny
sumber
0

Anda dapat membungkusnya dengan kondisi shell, misalnya:

[ "$(find . ...)" '!=' '' ] && echo Found || echo Not found

Di mana ...kondisi pertandingan Anda, mis -name *.txt.

Beberapa contoh lain:

[ "$(find /etc -name hosts)" ] && echo True || echo False
[ ! -z "$(find /etc -name hosts)" ] && echo True || echo False
kenorb
sumber