muru'nun cevabı , dosya bulunursa bir şey yazdırmak istediğimiz durumlar için uygun ve uygundur. Genel durum için harici komut yürütmek istediğimizde, örneğin bayrak echo
kullanabiliriz -exec
.
$ find . -name 'xac' -exec echo "I found " {} \; -quit
I found ./xac
{}
Parçası arasındaki komut için bir dosya adı geçen -exec
ve \;
bağımsız değişkenler olarak. Not \
önce ;
- bu engeller yanlış yorumlayarak gelen kabuk; noktalı virgül anlamına hangi komutun sonuna fakat eğik çizgiyle zaman, kabuk geçirilecek literall metin olarak algılar kabuk kapanış find
komuta ve kapanış olarak hizmet veren komutu bulmak için -exec
bayrağı'nın argümanlar.
if found do this; else do that
Sıralama koşullarını oluşturmak için, komut alt bölümünü $()
ve test
(aka [
) komutunu kullanabiliriz :
$ [ "x$(find . -name 'noexist' -print -quit)" != "x" ] && echo "found" || echo "not found"
not found
$ [ "x$(find . -name 'xac' -print -quit)" != "x" ] && echo "found" || echo "not found"
found
Dan'ın yorumuna değinmek
Dan yorumlarda sordu:
"{}" Bulduğum yankı "{" bulduğum "yankıdan daha iyi olmaz mıydı? Belki yankı için sorun değil, ama birisi komutu kopyalar ve yankıyı başka bir komutla değiştirirse sorun yaşayabilir
Önce sorunu anlayalım. Genellikle, kabuklarda sözcük bölme kavramı vardır, bu da alıntılanmamış değişkenler ve konumsal parametrelerin genişletileceği ve ayrı öğeler olarak ele alınacağı anlamına gelir. Örneğin, değişken varsa var
ve içerdiği hello world
metni bunu yaptığında, touch $var
kabuk iki ayrı öğeler içine yıkmak olacak hello
ve world
ve touch
size 2 ayrı dosya oluşturmak için çalışıyormuş gibi olduğunu anlayacaktır; bunu yaparsanız touch "$var"
, kabuk hello world
tek bir birim gibi davranır ve touch
yalnızca bir dosya oluşturur. Bunun sadece mermilerin nasıl çalıştığından dolayı olduğunu anlamak önemlidir.
Aksine, find
bu tür davranışlardan muzdarip değildir, çünkü komutlar find
kendi kendine işlenir ve execvp()
sistem çağrısı tarafından yürütülür , bu nedenle herhangi bir kabuk yoktur. Kıvırcık parantezlerin kabuklarda özel bir anlamı find
olsa da, başlangıçta değil , komutun ortasında görünürler , bu durumda kabuk için özel bir anlam taşımazlar. İşte bir örnek. Birkaç zor dosya adı oluşturalım ve bunları stat
komuta argümanı olarak geçirmeye çalışalım .
$ touch with$'\t'tab.txt with$' 'space.txt with$'\n'newline.txt
$ find -type f -exec stat -c "%F" {} \; -print
regular empty file
./with?newline.txt
regular empty file
./with space.txt
regular empty file
./with?tab.txt
Gördüğünüz gibi, stat
zor dosya adlarını mükemmel şekilde alır find
, bu da taşınabilir komut dosyalarında kullanılmasının önerilmesinin ana nedenlerinden biridir ve özellikle dizin ağacında gezinirken ve potansiyel olarak olabilecek dosya adlarıyla bir şey yapmak istediğinizde yararlıdır özel karakterler. Bu nedenle, çalıştırılan komutlar için süslü parantez alıntılamak gerekli değildir find
.
Mermi karıştığında farklı bir hikaye. Bazen dosya adını işlemek için bir kabuk kullanmanız gerekir. Bu durumda, alıntı yapmak gerçekten önemli olacaktır, ancak bulmanın problemi olmadığını fark etmek önemlidir - kelime bölünmesini yapan kabuktur.
$ find -type f -exec bash -c "stat {}" sh \;
stat: cannot stat './with': No such file or directory
sh: line 1: newline.txt: command not found
stat: cannot stat './with': No such file or directory
stat: cannot stat 'space.txt': No such file or directory
stat: cannot stat './with': No such file or directory
stat: cannot stat 'tab.txt': No such file or directory
Kabuk içinde alıntı yaptığımızda işe yarayacak. Ama yine, bu kabuk için önemli, değil find
.
$ find -type f -exec bash -c "stat -c '%F' '{}'" sh \;
regular empty file
regular empty file
regular empty file
/some/path
Nereden bakmaya başlayacağını söyler, ama hiçbir şey ona neye bakacağını söylemez. Bağlantılı cevabınızla aynı. Benim için ne işe yarıyorfind /some/path -name xac -print0 -quit | grep -qz . && echo found
. Bir şey mi kaçırdım?