"Bul" öğesinin herhangi bir eşleşme bulup bulmadığını nasıl tespit edebilirim?


16

Herhangi bir eşleşme bulunup bulunmadığını tespit etmek için deyimsel bir yöntem var mı? Şu anda kullanıyorum

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

ama bu benim için biraz dolaylı görünüyor. Ayrıca, bir eşleşme bulunduğunda aramayı durdurmak istiyorum, bu yüzden zaman ve çaba harcamaz. Sadece eşleşen herhangi bir dosya olup olmadığını bilmek gerekir.

Güncelleme: Önümdeki kod olmadan sorumu yazarken hata yaptım: wc -lBulunan toplam dosya sayısını bilmem gereken başka bir durumda kullanıyorum . Sadece herhangi bir eşleşme olup olmadığını test ettiğimde kullanıyordum if [ -z $(find …) ].

Yanıtlar:


17

GNU bulmanız gerektiğini biliyorsanız -quit , ilk maçtan sonra durdurmak için kullanın .

Portably, findiçine çıkışını boru head -n 1. Bu şekilde findbirkaç eşleşmeden sonra kırık bir borudan ölecektir (doldurulduğu zaman headarabellek).

Her iki durumda da, wcbir dizenin boş olup olmadığını test etmeniz gerekmez , kabuk bunu kendi başına yapabilir.

if [ -n "$(find … | head -n 1)" ]; then …

İlginç ... -nSadece 'tanımlanmış' değişkenlere ($ abc, $ xyz, vb.) Uygulandığını düşündüm , ancak $ (...) 'tanımlanmış' geçici bir değişken olduğunu varsayalım .. +1 ... (ve ben sadece Son zamanlarda -n, değişkenin zaten bildirilmediğinden ve 'kullanılmadığından emin olmadığınız sürece, kullanımın riskli olduğunu okuyun ... ama bir sıcaklık bu olasılığa sahip olmayacak ... yani. başlatılmamış ve boş
Peter.O

2
@fred: Aksine, -nbir dizenin boş olup olmadığını test eder, değişkenlerle ilgisi yoktur. Okuduğunuz şey muhtemelen kullanmanın -nbir değişkenin tanımlanıp tanımlanmadığını test etmediğini söylüyor : tanımlanmış ancak boşsa -n "$foo"yanlış foove altında bir hata mesajı gösteriyor set -u. ayarlanıp ayarlanmadığını [ -n "${foo+1}" ]güvenilir bir şekilde test eder foo, ancak boş ve ayarlanmamış değişkenlere aynı şekilde davranmak genellikle iyi bir fikirdir: [ -n "${foo:+1}" ]veya sadece [ -n "$foo" ]endişelenmiyorsanız set -u.
Gilles 'SO- kötü olmayı kes

Teşekkürler! Ben -quitmevcut değil , ama boru head -n 1işleri ( head -c 1daha önce durur gibi, ama muhtemelen ihmal edilebilir yarar). Ayrıca, önümde kod olmadan sorumu yazarken hata yaptım: wc -lBulunan dosyaların toplam sayısını bilmem gereken farklı bir durumda kullanıyorum . Sadece herhangi bir eşleşme olup olmadığını test ettiğimde kullanıyordum if [ -z `find … ` ].
Chris Page

6

-quitİlk maçtan sonra durdurmak için eylemi kullanabilirsiniz . Muhtemelen bunu başka bir eylemle (örneğin -print) birleştirmek isteyeceksiniz veya herhangi bir şey bulup bulamadığını söyleyemeyeceksiniz.

Örneğin, find ... -print -quiteşleşen ilk dosyanın yolunu yazdırır ve sonra çıkar. Ya da -printf 1 -quitbir eşleşme varsa 1'i basmak için kullanabilirsiniz ve eğer yoksa hiçbir şey.

findadlı kullanıcının çıkış durumu, bir şey bulup bulmadığını değil, arama sırasında hata olup olmadığını yansıtır, bu nedenle bir eşleşme olup olmadığını görmek için çıktısını kontrol etmeniz gerekir.


-quitbir GNU oluşumudur. OS X, BSD'ler ve muhtemelen çoğu ticari Unice gibi find (1) 'in diğer uygulamalarını kullanan sistemlerde çalışmaz.
Warren Young

Teşekkürler, başka bir sistem kullanmam durumunda bunu bilmek faydalıdır. Ne yazık ki, benimkinden -quit veya -printf kullanılamıyor (Mac OS X).
Chris Page

4

0 ile çıkış bulmak kolaydır, çıkış> 0 daha zordur çünkü bu genellikle sadece bir hata ile olur. Ancak bunu gerçekleştirebiliriz:

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

Bu çözümün bir alt kabuk kullanmaktan daha performanslı olduğunu unutmayın; false uygulamak, Dash'i uygulamaktan kesinlikle daha hızlıdır:

$ 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

0

Kabuk durumuna sarabilirsiniz, örneğin:

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

Eşleşme ...durumunuz nerede , ör -name *.txt.

Diğer bazı örnekler:

[ "$(find /etc -name hosts)" ] && echo True || echo False
[ ! -z "$(find /etc -name hosts)" ] && echo True || echo False
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.