Soru Boruyu nasıl ekleyebilirim | linux'umda -exec komutunu buldun mu?


Bu çalışmıyor. Bu keşifte yapılabilir mi? Yoksa xargs'a ihtiyacım var mı?

find -name 'file_*' -follow -type f -exec zcat {} \| agrep -dEOE 'grep' \;

166
2017-11-20 22:01


Menşei




Cevaplar:


Boru sembolünü çoklu süreçleri çalıştırmak ve bir işlemin çıkışını başka bir işlemin girişine aktarmak için bir komut olarak yorumlama işi, kabuğun (/ bin / sh veya eşdeğeri) sorumluluğudur.

Örneğinizde, boruyu yapmak 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 keşif, zkat'ın çok sayıda çağrılması ve bir agrep'in bir çağrılmasını gerektirmektedir.

Bu, sadece çok sayıda zcat tarafından üretilen tüm çıktıları işleyecek olan tek bir agrep sürecinin ortaya çıkmasına neden olacaktır.

Bir nedenden dolayı agrep'i birden çok kez çağırmak isterseniz, şunları yapabilirsiniz:

find . -name 'file_*' -follow -type f \
    -printf "zcat %p | agrep -dEOE 'grep'\n" | sh

Bu, yürütmek için boruları kullanan komutların bir listesini oluşturur, ardından bunları gerçekte yürütülmesi için yeni bir kabuğa gönderir. ("| Sh" kelimesinin sonlandırılması, bunun gibi komut satırlarının kuru çalışmalarının ya da hata ayıklamalarının güzel bir yoludur.)

Verimlilik açısından, bu sonuç bir buluntunun çağrılmasını, bir şahın çağrılmasını, çok sayıda zcat ve agrep'in çok sayıda çağrılmasını gerektirmektedir.

Komuta çağrılarının sayısı açısından en verimli çözüm Paul Tomblin'in önerisi:

find . -name "file_*" -follow -type f -print0 | xargs -0 zcat | agrep -dEOE 'grep'

... bir buluntunun çağrılmasını, bir tane de xargs'ı, bir kaç zcat ve bir agrep'i çağırmayı gerektiriyor.


117
2017-11-20 22:42



Xargs'ın bir diğer avantajı, -P anahtarını (-P 0) kullanarak modern çok çekirdekli işlemci ile daha da hızlandırabilmeniz olacaktır. - flolo
Evet, -P swich gerçekten de genel olarak infazı hızlandırmak için iyi bir yol. Ne yazık ki, paralel zcat işlemlerinin çıktısını agrep araya getirilmiş agrep içine geçirme riskini çalıştırırsınız, bu da sonucu etkiler. Bu etki şu şekilde gösterilebilir: echo -e "1 \ n2" | xargs -P 0 -n 1 evet | uniq - Rolf W. Rasmussen
@Adam, önerdiğin değişikliği yaptım. - Paul Tomblin
görkemli xjobs komutunu yükleyebilirsiniz (orijinal olarak Solaris'den) - sehe
Daha basit ve daha genel bir cevap stackoverflow.com/a/21825690/42973: -exec sh -c "… | … " \;. - Eric Lebigot


çözüm kolaydır: sh ile çalıştır

... -exec sh -c "zcat {} | agrep -dEOE 'grep' " \;

212
2017-11-20 22:40



OP'nin başarmaya çalıştığı şey yukarıdaki önerilerle karşılanabilir, ancak sorulan soruya gerçekten cevap veren budur. Bunu bu şekilde yapmanın nedenleri var - exec, özellikle testle birleştirildiğinde, buldukları dosyalar üzerinde çalışmaktan çok daha güçlüdür. Örneğin: geda-gaf / -type d -exec'i bul bash -c 'DIR = {}; [[$ ($ DIR -maxdepth 1 | xargs grep -i baharat | wc -l) -ge 5]] && echo $ DIR '\; Arama dizinindeki tüm dizinleri, söz konusu dizinde bulunan ve "spice" sözcüğünü içeren tüm dosyalar arasında toplamda 5 satırdan oluşan toplam dizinleri döndürür. - swarfrat
En iyi cevap. Tüm çıktıyı çırpmak (diğer cevaplar gibi) her dosyada grep ile aynı değildir. İpucu: sh yerine istediğiniz başka bir kabuk kullanabilirsiniz (bunu bash ile denedim ve işe yarıyor). - pagliuca
Gözden kaçırmayın emin olun -c seçeneği. Aksi halde bir şaşıracaksınız No such file or directory hata mesajı. - asmaier
Burada exec'd kabuğunun içinde boru ile bulmayı kullanan harika bir ps değiştirme: / usr / bin / find / proc -mindepth 1 -maxdepth 1 -type d -regex '. * / [0-9] +' - print -exec bash -c "cat {} / cmdline | tr '\\ 0' ''; echo" \; - parity3
Dosya bulma ve bunları yeniden adlandırma örneği sed düzenli ifade kullanarak find -type f -name '*.mdds' -exec sh -c "echo {} | sed -e 's/_[0-9]\+//g' | xargs mv {}" \; - Rostfrei


find . -name "file_*" -follow -type f -print0 | xargs -0 zcat | agrep -dEOE 'grep'

15
2017-11-20 22:04



Verimlilik nedenleriyle -baskı ve xargs önlemek umuduyla. Belki de bu gerçekten benim problemim: bul, piped komutları -exec ile işleyemez - someguy
Bu, adlarında boşluk bulunan dosyalarla çalışmaz; düzeltmek için -print0 ile -print0 ile değiştirin ve xargs'e -0 seçeneğini ekleyin - Adam Rosenfield
@someguy - Wha? Verimlilik nedeniyle xargs kullanmaktan kaçının mı? Bir zcat örneğini çağırıp, birden çok dosyanın bir listesini geçirerek, uzak Bulunan her dosya için yeni bir örneğini yürütmekten daha verimli. - Sherm Pendley
@Adam - Önerilen değişikliklerinizi yaptım. Bulduğum zamanın% 99'u, kaynak kod dizinlerimde ve hiçbir dosyada boşluk yok, bu yüzden print0 ile uğraşmam. Şimdi benim belgeler dizini, diğer taraftan, ben print0 hatırlıyorum. - Paul Tomblin


Ayrıca bir while Dosyada birden çok eylem gerçekleştirebilen döngü find bulur. Yani burada bakmak için bir jar belirli bir java sınıf dosyası için arşivleri büyük bir dağıtım ile klasörde jar Dosyalar

find /usr/lib/eclipse/plugins -type f -name \*.jar | while read jar; do echo $jar; jar tf $jar | fgrep IObservableList ; done

anahtar nokta şu ki while döngü, noktalı virgülle ayrılmış dosya adına geçirilen birden çok komut içerir ve bu komutlar borular içerebilir. Yani bu örnekte, eşleşen dosyanın adını ekledikten sonra belirli bir sınıf adı için arşiv filtresinde ne olduğunu listeleyeceğim. Çıktı gibi görünüyor:

/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 / tutulma / çekirdek / veri bağlama / gözlemlenebilir / liste /IObservableList.sınıf /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

benim bash kabuğumda (xubuntu10.04 / xfce) gerçekten eşleşen sınıf adını kalın olarak yapar fgrep Eşleşen dizeyi vurgular; Bu yüzlerce listeyi taramak gerçekten kolay hale getirir jar Aranan ve kolayca herhangi bir eşleşme görmek dosyaları.

Pencerelerde aynı şeyi yapabilirsiniz:

for /R %j in (*.jar) do @echo %j & @jar tf %j | findstr IObservableList

pencerelerde bu komut ayırıcısının '&' değil '; ve '@', yukarıdaki linux çıktısı gibi düzenli bir çıktı vermek için komutun yankısını bastırır; olmasına rağmen findstreşleşen dize kalın değil, böylece eşleşen sınıf adını görmek için çıktıya biraz daha yakından bakmak zorunda. Pencereler için 'for' komutunun metin dosyaları arasında dolaşmak gibi bir kaç hileyi bildiği ortaya çıkıyor.

keyfini çıkarın


8
2017-09-18 12:01