Bir 'find -exec'i başka bir' find -exec 'içine yerleştirmek mümkün mü?


14

Aşağıdaki gibi bir şey peşinde olduğum şey, ama nasıl kaçar {}ve+ ;

find ./ -maxdepth 1 -type d -name '.*' -exec \
    find {} -maxdepth 1 -type f -name '*.ini' -exec \
        md5sum \{\} \\; \;

Bu gördükten sonra & - - Unix, Linux soru , ben aşağıdaki kod eserler bulundu, ancak iç içe değil bulmak gibi ve ben bu belirli bir iş yapmak için daha iyi bir yol yoktur sanıyorum.

find ./ -maxdepth 1 -type d -name '.*' \
-exec bash -c 'for x; do
    find "$x" -maxdepth 1 -type f -name "*.ini" \
    -exec md5sum \{\} \;; \
done' _ {} \+

find -execBir kabuğunu çağırmaya gerek kalmadan yuva yapmanın bir yolu var mı ?

Veya bu, birçok parametresinin bir karışımı kullanılarak doğrudan tek bir find komutunda yapılabilir mi?


4
Sorduğunuz şeyi yapmak mümkün olsa da, işler karmaşıklaştığında, kabuk veya Perl komut dosyalarına geçiyorum. İkinci kod snippet'iniz bunu sadece kabuk betiği satır içi ile yapıyor. Kahramanca tek gömlekler eğlencelidir, ancak anlaşılması zordur ve bu nedenle bakımı zordur. Bu, yine de bir şekilde iyi olmaya başladığınız tek seferlik bir anlaşma olmadığı sürece, bunu entelektüel zorluktan başka yapmak için iyi bir neden göremiyorum.
Warren Young

1
@Warren Genç: Kesinlikle kavram karmaşık olduğunu düşünmüyorum, ama orada hiçbir anlamına varsayalım basit İle yapmanın yolu find, ama eğer findbunu yapamaz, o zaman neden olduğunu findbu yüzden saygı (?) Araç-olarak dosyaları bulmak için kullanmak için? ... find ./ -maxdepth 2 -path '.*/*.ini' -type f -exec md5sum {} \+müteakip olarak benim durumumda iyi buldum buldum (jw013 referansı -prunebeni man sayfasında bu götürdü), ama ben bu sağlam bir yöntem (cins) olup olmadığını merak ediyorum. Asla ihtiyacım olan her şeyi yaptığı findgibi (Linux'un bir yıldan az bir sürede) gerçekten kullanmadım locate, bu yüzden bilinmeyen bölge.
Peter.O

1
-pathTest ben önerecektim tam olarak ne olduğunu. Bununla, yapmanız gerekir istediğin o (Taban dernek Ace için üzgünüm;))
rozcietrzewiacz

Yanıtlar:


8

Gibi tek bir bulmayı kullanarak denemek istiyorsunuz:

find .*/ -maxdepth 1 -type f -name '*.ini' -execdir md5sum {} +

veya hatta (hayır find, sadece kabuk zonklama)

md5sum .*/*.ini

Her ne kadar bu -type fkontrol eksik olsa da sadece hiçbir dizin / dosya ile biten dosya yoksa çalışır .ini. Eğer yaparsan kullanabilirsin

for x in .*/*.ini; do 
    if [ -f "$x" ]; then 
        md5sum "$x"
    fi
done

ancak bu sadece bir md5sum çağrısına ihtiyaç duyma avantajını kaybeder.

Düzenle

Zincirleme genel ve güvenli yöntem için find, aşağıdaki gibi bir şey yapabilirsiniz

find <paths> <args> -print0 | xargs -0 -I{.} find {.} <args for second find> [etc.]

Birlikte bir hata alıyorum -f(? F) ve sonra başka bir hata -execdirben değiştirdiğinizde .. -execdir -exec ile ve / veya ayrıca baskı ile md5sum yerine, hiçbir şey elde ..
Peter.O

Teşekkürler, alternatif için ... ama ben bunu kullanarak bir yoldan sonra daha find... Ben sadece bu örneğin çözülmesini istiyorum değil, ben find-fu yolları hakkında bilgi arıyorum .. Belki de bulmakta fu daha kabartmak var .. (Bilmiyorum, çünkü neredeyse hiç kullanmadım) ve bu gerçekten kullanmak istediğim ilk durum (aslında görüntü dosyaları için) ve - Çok fazla şey duyduğum exec özelliği, rep (?) 'in ima ettiği kadar güçlü değil gibi görünüyor ... (alternatifler için +1 olsa da) .. ancak findörneğiniz işe yaramıyor (hala )
Peter.O

findKomut için bu hatayı alıyorum : ... find: The relative path ~ / bin ', find -execdir eylemiyle birlikte güvensiz olan PATH ortam değişkenine dahil edilmiştir. Lütfen bu girişi $ PATH`den kaldırın .... Bu yüzden belki işe yarar, ama bir süredir bu ~ / bin'den kurtulmaya çalıştığımı söylemeliyim ... Daha fazla almak zorunda kalacağım ciddi bak ... Nereye koyduğumu bilmiyorum ... nerede gizlendiğine dair herhangi bir fikir; ~/binBenim PATH içinde
Peter.O

Bence gücünün finden iyi şekilde tamamen glob ile yapılamayan durumlarda takdir edildiğini düşünüyorum , ancak bu tür durumlar nadir olduğu için normalde fazla bulmam gerekmiyor.
jw013

Tamam .. Bu ilginç ve iyi bir nokta (
glob kullanımı

2

Orijinal sorununuz yinelenen arama bulmayı gerektirmez, ancak bunun önemli olmadığını düşünüyorum.

Bulmayı istediğiniz şekilde yinelemeli olarak çağırmanın mümkün olmadığına inanıyorum.

Aşağıdakiler de yinelemeli olarak find (ya da her ne denirse iç içe geçme) çağrısı yapmaz, ancak ilk bulgunun bir sonuç kümesini alıp ikincisine besleyemez misiniz? Ben içgüdüsel olarak şöyle yaparım:

find `find ./ -maxdepth 1 -type d -name '.*'` \
    -maxdepth 1 -type f -name '*.ini' -exec md5sum {} \;

xargsİkinci bulguyu yürütmek için de kullanabilirsiniz .

Güncelleme:

Çoğu UNIX yardımcı programı biri yerine birkaç dosya adı bağımsız değişkeni aldığından, genellikle -exectamamen önleyebilirsiniz :

md5sum `find \`find ./ -maxdepth 1 -type d -name '.*'\` -maxdepth 1 -type f -name '*.ini'`

İğneleri yuvalarken \iç kısımlardan önce ters eğik çizgiler eklersiniz .

Bunun md5sumyalnızca bir dosya adı argümanı gerektirdiğini hayal edersek, bunu her zaman bir fordöngü içinde sarabiliriz :

for f in `find \`find ./ -maxdepth 1 -type d -name '.*'\` -maxdepth 1 -type f -name '*.ini'`
do
    md5sum $f
done

-Bir boşlukla başlayan veya boşluk içeren dosya / dizin adları söz konusu olduğunda bunun daha zor olacağını unutmayın . UNIX yardımcı programları onlarla iyi oynamıyor. Bu durumda ekleyerek ./, --ya da tırnak ihtiyaç vardır.

Açıkçası orijinal örnek iyi bir örnek değil, çünkü yapabiliriz:

md5sum .*/*.ini

1
Durum hakkında iyi bir genel bakış sağladınız, ancak bir dosya / dizin boşluk içerdiğinde gösterilen findyöntemlerin tümü hatamd5sum .*/*.ini veriyor ... İyi çalışıyor ... * Warren Young'ın * 'karmaşık' hale gelen şeyler hakkında yorum yapmak findoyunun başlarında gerçekleşiyor :), ancak findkoşul testleri daha karmaşık olduğunda kendi başına geldiğini varsayıyorum , ancak yuvalama -exec'in gittiği kadarıyla, fikri oldukça iyi bıraktım, Görünüşe göre bunu yapmanın daha basit yolları var .. (ama perl benim için henüz "basit" değil ...
Peter.O

0

En azından 2 find komutunu iç içe yerleştirmeyi başardım:

find ~ -maxdepth 1 -type d -name '.*' -execdir \
    find {} -maxdepth 1 -type f -name '*.ini' \;

Ama oradan başka bir -exec (dir) - çağrısı çağırmayı çözemedim.


Evet, bu benim sorunum tam olarak :)
Peter.O

Evet, ancak yuvalama 3 yuvalama 2 ile aynı değildir. :)
kullanıcı bilinmiyor
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.