bulmak -exec + vs bulmak | xargs: hangisini seçmeli?


32

Davranışını taklit etmek için -execbir +seçenek alabileceğini anlıyorum xargs. Bir formu diğerine tercih ettiğiniz herhangi bir durum var mı?

Şahsen ben sadece boru kullanmaktan kaçınmak için ilk şekli tercih etme eğilimindeyim. Kesinlikle geliştiricilerin finduygun optimizasyonları yapmaları gerektiğini düşünüyorum. Doğrumuyum?

Yanıtlar:


21

Bulmak için aramaları zincirlemek isteyebilirsiniz (bir kez, öğrendiğinizde, bunun mümkün olabileceğini, bunun bugün olabilir). Bu, elbette, ancak siz kaldığınız sürece mümkündür. Xargs'a bir kez boru bağladığınızda kapsam dışında.

Küçük örnek, iki dosya a.lst ve b.lst:

cat a.lst
fuddel.sh
fiddel.sh

cat b.lst
fuddel.sh

Burada numara yok - sadece her ikisinin de "fuddel" içerdiği, ancak sadece birinin "fiddel" içerdiği gerçeği.

Bunu bilmediğimizi varsayalım. 2 koşulla eşleşen bir dosya arıyoruz:

find -exec grep -q fuddel {} ";" -exec grep -q fiddel {} ";" -ls
192097    4 -rw-r--r--   1 stefan   stefan         20 Jun 27 17:05 ./a.lst

Belki grep ya da başka bir programın sözdizimini koşul olarak her iki dizeyi de geçirirsiniz, ama mesele bu değil. Argüman olarak bir dosya verildiğinde doğru veya yanlış dönebilen her program burada kullanılabilir - grep sadece popüler bir örnekti.

Ve not, sen takip edebilir -exec bulmak gibi diğer bulmak komutlarla -LS veya -sil veya benzer bir şey. Unutmayın ki silme yalnızca rm (dosyaları kaldırmaz) değil, rmdir (dizinleri de kaldırır).

Bu tür bir zincir, aksi belirtilmediği sürece (yani bir -oranahtarla (ve parens (maskeleme))) AND komutlarının bir kombinasyonu olarak okunur .

Yani kullanışlı bir şey olan bulma zincirinden ayrılmıyorsunuz. -Xargs kullanmanın hiçbir avantajı görmüyorum, çünkü dosyaları aktarırken dikkatli olmanız gerekiyor, ki bu yapmanız gereken bir şey değil - her dosyayı sizin için tek bir argüman olarak geçirmeyi otomatik olarak ele alıyor.

{} Kaşlı ayraçlar için biraz maskeleme gerektiğine inanıyorsanız , delil isteyen soruyu ziyaret etmekten çekinmeyin. Benim iddiam şudur: Yapmazsın.


3
Bu yazı gözlerimi yeni kullanmanın bir yolunu açtı find. Çok teşekkürler!
rahmu

1
Msgstr "-xargs kullanımında hiçbir avantaj görmüyorum". Dört çekirdeğin üçünün boşta kalmaması için -execyapmanın yolu nedir xargs -P4?
Damian Yerrick 25:16,

1
@DamianYerrick: -exec komutunu ";" ancak bir + (/ artı işareti) ile.
kullanıcı bilinmeyen

25

Seçeneklerinizi desteklemenizi ve dosyalarınızı okumak için ( veya ) karşılık gelen seçeneğe sahip xargsolmanızı gerektiren dosya adlarını güvenle pipolayın . Aksi takdirde, adında yazdırılamayan karakterler veya ters eğik çizgiler veya tırnak işaretleri veya boşluk içeren dosya adları beklenmeyen davranışlara neden olabilir. Öte yandan, olduğu POSIX spec o taşınabilir, böylece, ve o kadar güvenli olarak hakkındadır ve daha kesinlikle güvenlidir . Ben tavsiye ederim asla yapıyor olmadan .find-print0xargs--null-0find -exec {} +findfind -print0 | xargs -0find | xargsfind | xargs-print0


6
Taşınabilirliği için dikkate değer bir istisna find … -exec … {} +, yalnızca 2012'de piyasaya sürülen 5.1 sürümüyle bu özelliği edinen -print0OpenBSD'dir. Alacağınız bu yüzden Solaris, diğer taraftan, POSIX'e sopalarla sahiptir -exec +hayır ve -print0.
Gilles 'SO- kötü olmayı bırak'

-print0Bu bir acıdır ve xargs --delimiter "\n"eşdeğer olmadığını iddia edebilseniz de, ikincisini keşfettikten sonra hiçbir zaman eskisini kullanmadım.
Sridhar Sarnobat

3
Nasıl -0bir acıdan daha fazla olduğunu anlamıyorum --delimiter "\n".
jw013

2
Buna ek olarak -0, eğer giriş yoksa GNU'nun komutu çalıştırmasından kaçınması xargsgerekir -r.
Stéphane Chazelas 11:15

2
Bir başka sorun | xargs -r0 cmdolduğunu cmd'ın Stdin (etkilenen bağlı olduğu xargsuygulanması, bu kadar /dev/nullveya boru.
Stéphane Chazelas

10

-exec ... ;Formu kullanırsanız (noktalı virgülden kaçmayı unutmayın), komutu her dosya adı için bir kez çalıştırıyorsunuzdur. Kullanırsanız -print0 | xargs -0, dosya adı başına birden çok komut çalıştırın. -exec +Birden çok dosyayı tek bir komut satırına yerleştiren ve çok sayıda dosya bulunduğunda daha hızlı olan formu kesinlikle kullanmalısınız .

Kullanımın büyük bir artısı, xargsparalel komut kullanarak çoklu komutları çalıştırma yeteneğidir xargs -P. Çok çekirdekli sistemlerde, büyük zaman tasarrufu sağlayabilir.


6
Onun -Pyerine demek istedin -p. xargs -PPOSIX standardında değil, find -exec {} +taşınabilirlik için önemli olan akılda tutulmalıdır .
jw013

@Alexios Artı işaretinden kaçmanız gerekmez, çünkü kabuk için özel bir anlamı yoktur: find /tmp/ -exec ls "{}" +gayet iyi çalışır.
daniel kullmann

1
Tabii ki Corrent. Ben sonra her şeyi kaçan oldum -execbu kadar uzun süre (ben bile kaçmaya tırnak kullanmayın, bir mazoşist değilim {}, hep yazın \{\}; sormayın), hiç böyle bir şey görünüyor şimdi öncelenmelidir.
Alexios

1
@Alexios: Parantezlerin maskelenmesinin yararlı olduğu bir örnek (mazoşist olmak dışında) bulursanız, lütfen buradaki soruma bir cevap olarak verin - bu ipucunun modası geçmiş olması ve yalnızca sayfadaki bir kalıntı olması. Asla find /tmp/ -exec ls {} +işe yaramayacak bir örnek görmedim .
kullanıcı bilinmeyen

1
Benim için bu SunOS 4 günlerinde oluşan kas hafızasıdır. Yıllardır yaptığımdan beri bash, ayraçları kabul etmeye başladığımda tamamen fark etmedim . Kullandığım eski mermilerden en az birinin, diş telleri çıkmamışsa, telaşlı bir şekilde uyduğundan eminim.
Alexios

8

Performans -exec … +konusunda daha iyi olacağını düşündüm, çünkü tüm işi yapan tek bir araç, ancak GNU findut'un belgelerinin bir kısmı,-exec … + bazı durumlarda daha az etkili olabileceğini söylüyor :

[bul -exec … +] , bazı kullanımlardan daha az verimli olabilir xargs; Örneğin xargs, önceki komut hala yürütülürken yeni komut satırlarının oluşturulmasına izin verir ve paralel olarak çalışacak bir dizi komut belirlemenizi sağlar. Bununla birlikte, find ... -exec ... +yapı geniş taşınabilirlik avantajına sahiptir. GNU bulguları 4.2.2 [Ocak 2005]-exec ... + sürümüne kadar ' ' desteklemiyordu ; Bunun nedenlerinden biri, her durumda zaten ' ' eylemi yapmış olmasıdır.-print0

Bunun ne anlama geldiğinden tam olarak emin değildim, bu yüzden derobert'in şöyle açıkladığı sohbette sordum :

findbüyük olasılıkla -exec … +, çalışırken bir sonraki dosya grubunu aramaya devam edebilir , ancak çalışmaz.
find … | xargs …yapar, çünkü o zaman bulucu farklı bir işlemdir ve boru arabelleği doluncaya kadar çalışmaya devam eder.

(Benim tarafımdan biçimlendirme.)

İşte bu var. Ancak performans gerçekten önemliyse, gerçekçi kıyaslama yapmak zorunda kalacaksınız veya hatta bu tür durumlarda kabuk kullanmak isteyip istemediğinizi kendinize sorabilirsiniz.

Burada bu sitede, insanlara -exec … +formu mümkün olan her durumda kullanmalarını tavsiye etmenin daha iyi olacağını düşünüyorum çünkü sadece daha basit olduğu için ve buradaki diğer cevaplarda belirtilen nedenlerden dolayı (örneğin, çok fazla düşünmek zorunda kalmadan garip dosya adlarını kullanmak).

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.