Yanıtlar:
Boru sembolünü birden çok işlem yürütme talimatı olarak yorumlama ve bir işlemin çıktısını başka bir işlemin girişine aktarma işi kabuğun (/ bin / sh veya eşdeğeri) sorumluluğudur.
Örneğinizde, boruları şu şekilde gerçekleştirmek için en üst düzey kabuğunuzu kullanmayı seçebilirsiniz:
find -name 'file_*' -follow -type f -exec zcat {} \; | agrep -dEOE 'grep'
Verimlilik açısından, bu sonuç bir bulma çağrısına, çok sayıda zcat çağrısına ve bir agrep çağrısına mal olur.
Bu, çok sayıda zcat çağrısının ürettiği tüm çıktıları işleyecek olan tek bir agrep sürecinin ortaya çıkmasına neden olacaktır.
Herhangi bir nedenle agrep'i birden çok kez çağırmak istiyorsanız, şunları yapabilirsiniz:
find . -name 'file_*' -follow -type f \
-printf "zcat %p | agrep -dEOE 'grep'\n" | sh
Bu, yürütmek için borular kullanarak komutların bir listesini oluşturur, ardından bunları gerçekten yürütülecek yeni bir kabuğa gönderir. (Son "| sh" yi atlamak, böyle komut satırlarının kuru çalışmalarını hata ayıklamak veya gerçekleştirmek için iyi bir yoldur.)
Verimlilik açısından, bu sonuç bir bulma çağrısına, bir sh çağrışmasına, çok sayıda zcat çağrısına ve çok sayıda agrep çağrısına mal olur.
Komut çağırma sayısı açısından en etkili çözüm Paul Tomblin'in önerisidir:
find . -name "file_*" -follow -type f -print0 | xargs -0 zcat | agrep -dEOE 'grep'
... bir keşif çağrısı, bir xargs çağrısı, birkaç zcat çağrısı ve bir agrep çağrısı maliyeti.
-exec sh -c "… | … " \;
.
çözüm kolaydır: sh ile çalıştırın
... -exec sh -c "zcat {} | agrep -dEOE 'grep' " \;
-c
Seçeneği göz ardı etmediğinizden emin olun . Aksi takdirde kafa karıştırıcı bir No such file or directory
hata mesajı alırsınız.
find -type f -name '*.mdds' -exec sh -c "echo {} | sed -e 's/_[0-9]\+//g' | xargs mv {}" \;
find . -name "file_*" -follow -type f -print0 | xargs -0 zcat | agrep -dEOE 'grep'
Bulunan while
dosya üzerinde birden çok eylem gerçekleştirebilen bir döngüye find
yöneltebilirsiniz. Yani burada bakarak için biridir jar
büyük bir dağıtımla olan klasördeki belirli bir java sınıfı dosyası için arşivler jar
dosyaları
find /usr/lib/eclipse/plugins -type f -name \*.jar | while read jar; do echo $jar; jar tf $jar | fgrep IObservableList ; done
kilit nokta, while
döngünün noktalı virgülle ayrılmış dosya adında atıfta bulunan birden fazla komut içermesidir ve bu komutlar dikey çizgi içerebilir. Bu örnekte, eşleşen dosyanın adını yankılayıp belirli bir sınıf adı için arşiv filtrelemede ne olduğunu listeliyorum. Çıktı şöyle görünür:
/usr/lib/eclipse/plugins/org.eclipse.core.contenttype.source_3.4.1.R35x_v20090826-0451.jar /usr/lib/eclipse/plugins/org.eclipse.core.databinding.observable_1.2.0.M20090902-0800 .jar org / eclipse / core / databinding / gözlemlenebilir / list / IObservableList .class /usr/lib/eclipse/plugins/org.eclipse.search.source_3.5.1.r351_v20090708-0800.jar / usr / lib / eclipse / plugins / org.eclipse.jdt.apt.core.source_3.3.202.R35x_v20091130-2300.jar /usr/lib/eclipse/plugins/org.eclipse.cvs.source_1.0.400.v201002111343.jar / usr / lib / eclipse / plugins / org.eclipse.help.appserver_3.1.400.v20090429_1800.jar
bash kabuğumda (xubuntu10.04 / xfce) gerçekten eşleşen sınıf adını fgrep
, eşleşen dizeyi vurgularken kalın yapar ; bu, jar
aranan yüzlerce dosyanın listesini taramayı ve eşleşmeleri kolayca görmeyi gerçekten kolaylaştırır .
Windows'da aynı şeyi aşağıdakilerle yapabilirsiniz:
for /R %j in (*.jar) do @echo %j & @jar tf %j | findstr IObservableList
pencerelerde komut ayırıcısının '&' değil 'olduğunu unutmayın; ve '@' komutunun yankısını bastırır; tıpkı linux yukarıdaki çıktıyı buluyor gibi düzenli bir çıktı verir; her ne kadar findstr
eşleşen dize kalın yapmaz, bu yüzden eşleşen sınıf adını görmek için çıktı biraz daha yakından bakmak zorunda. 'For' komutunun pencerelerinin, metin dosyaları arasında döngü yapmak gibi birkaç püf noktası bildiği ortaya çıkıyor ...
zevk almak
Ben bir dize kabuk komutu (sh -c) çalışan en iyi, örneğin bulundu:
find -name 'file_*' -follow -type f -exec bash -c "zcat \"{}\" | agrep -dEOE 'grep'" \;
Basit bir alternatif arıyorsanız, bu bir döngü kullanılarak yapılabilir:
for i in $(find -name 'file_*' -follow -type f);do zcat $i | agrep -dEOE 'grep');done
veya daha genel ve anlaşılması kolay bir form:
for i in $(YOUR_FIND_COMMAND);do YOUR_EXEC_COMMAND_AND_PIPES );done
ve YOUR_EXEC_COMMAND_AND_PIPES içindeki {} ile $ i değerini değiştirin