Find kullanırken çoklu komutları nasıl uygularım?


57

Bulduğum şeyler üzerinde çoklu komut çalıştırmaya çalışıyorum, bunu nasıl başarabilirim?

find . -exec cmd1; cmd2

işe görünmüyor; bunun yerine her dosyada cmd1 çalıştırıldıktan sonra cmd2'yi çalıştırır.

Yanıtlar:


40

Bu gösteride ilk önce sh -c 'echo first; false'(veya true) kullanacağım -exec. Bu, bazı çıktılar verecek ve ayrıca seçilen çıkış kodu efektine sahip olacaktır. Sonra echo secondikincisi için kullanılacak. Geçerli dizinde bir dosya olduğunu varsayalım.

$ find . -type f -exec sh -c 'echo first; false' \; -exec echo second \;
first
$ find . -type f -exec sh -c 'echo first; true' \; -exec echo second \;
first
second
$ find . -type f \( -exec sh -c 'echo first; false' \; -false -o -exec echo second \; \)
first
second
$ find . -type f \( -exec sh -c 'echo first; false' \; -false -o -exec echo second \; \)
first
second

Bu tür gerçek bir komut şöyle görünür:

find . -type f \( -exec command1 \; -false -o -exec command2 \; \)

İkinci sette, kaçan parantezler iki -execmaddeyi gruplandırır . Bunlar -falsearasında test durumu "yanlış" olmaya zorlar ve bir -osonraki ifadenin (ikincisi -exec) nedeniyle değerlendirilmesine neden olur -false.

Kimden man find:

expr1 expr2
Bir satırdaki iki ifade, ima edilen "ve"; ifade1 yanlış ise ifade2 değerlendirilmez.

ifade1 -a ifade2 ifade1 ifade1 ile
aynıdır.

ifade1 -o ifade2
ya da; ifade1 doğruysa ifade2 değerlendirilmez.


Ah evet, unuttum -o.
Ignacio Vazquez-Abrams

32

Cmd1'in hata kodu nedeniyle cmd2'nin çalışmasını engelleyememesi önemli değilse 0:

find . -exec cmd1 \; -exec cmd2 \;

Her iki komutu da her zaman çalıştırmanın tek güvenilir yolu find, daha sonra komutları sırayla çalıştıracak bir kabuk çağırmaktır:

find . -exec bash -c 'cmd1; cmd2' filedumper {} \;

2

Eğer cmd1 ve cmd2'yi yapan bir betik hazırlamanın sakıncası yoksa, o zaman işte bu:

find . -exec myscript {} \;

veya

find . -exec myscript {} +

Kullanın \; veya +, myscript'in bir kerede birden fazla dosyayı işleyip işlemeyebileceğine bağlı olarak (dosya adlarında boşluk varsa vb.

Yaptıklarını bir senaryoya koymak, deneyimlerime göre, neredeyse her zaman buna değdi. Bir kez yapmak zorunda kalırsan, tekrar yapmak zorunda kalacaksın.

Ancak bulmacayı betiğin içine koymak için düzgün bir numara :

if [ $# -gt 0 ]; then
    for each; do
        touch $each
    done
else
    find . -exec $0 {} +
fi

Daha sonra myscript üzerinde çalışması için argüman olarak verdiğiniz dosyalar üzerinde çalışır, ancak herhangi bir argüman vermezseniz, geçerli dizinden bulmayı çalıştırır ve ardından bulunan dosyalar üzerinde kendisini çağırır. Bu, -exec'in betiğinizde tanımladığınız kabuk işlevlerini çağıramayacağı gerçeğini ortaya çıkarır.


0

Eskiden her iki çözümü de çok şanssız deniyorum. Bu benim için iyi çalıştı:

$ for i in `find . -exec echo {} \;`; do cmd1 $i; cmd2 $i; done

Dosya listesi çok büyükse bu işe yaramaz.
Alex,

-3

komutunu deneyin:

sudo find -name "*[!0-9][1-9].txt" -exec chmod 744 * {} \; -a -exec ls -l {} \; | sort | parallel ls -l

4
Eh, bu iyi bir fikir değil. *İçinde -execkısmen geçerli dizindeki tüm dosyalara genişleyecektir. Özellikle olarak çalışırken sudo.
slhck
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.