Próbuję uruchomić wiele poleceń na rzeczach, które znalazłem, jak mogę to osiągnąć?
find . -exec cmd1; cmd2
wydaje się nie działać; zamiast tego uruchamia cmd2 po wykonaniu cmd1 na każdym pliku.
Próbuję uruchomić wiele poleceń na rzeczach, które znalazłem, jak mogę to osiągnąć?
find . -exec cmd1; cmd2
wydaje się nie działać; zamiast tego uruchamia cmd2 po wykonaniu cmd1 na każdym pliku.
Odpowiedzi:
W tej demonstracji użyję sh -c 'echo first; false'
(lub true
) po raz pierwszy -exec
. To da jakieś wyjście, a także będzie miało wybrany efekt kodu wyjścia. Następnie echo second
zostanie wykorzystany do drugiego. Załóżmy, że w bieżącym katalogu jest jeden plik.
$ 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
Prawdziwe polecenie tego typu wyglądałoby następująco:
find . -type f \( -exec command1 \; -false -o -exec command2 \; \)
W drugim zestawie nawiasach ucieczkowych grupuje dwie -exec
klauzule. -false
Między nimi wymusza stan testu na „false” i -o
powoduje, że następnego wyrazu (drugi -exec
), aby być oceniane ze względu na -false
.
Od man find
:
wyrażenie1
wyrażenie2 Dwa wyrażenia z rzędu są łączone za pomocą domyślnych „i”; wyrażenie2 nie jest oceniane, jeśli wyrażenie1 jest fałszem.wyrażenie1 -a wyrażenie2 To
samo, co wyrażenie1 wyrażenie2.wyraż1 -o wyraż2
Or; wyrażenie2 nie jest oceniane, jeśli wyrażenie1 jest prawdziwe.
Jeśli nie ma znaczenia, że cmd1 może uniemożliwić uruchomienie cmd2 z powodu kodu błędu 0
:
find . -exec cmd1 \; -exec cmd2 \;
Jedynym niezawodnym sposobem, aby oba polecenia były zawsze uruchamiane, jest find
wywołanie powłoki, która następnie uruchomi polecenia w kolejności:
find . -exec bash -c 'cmd1; cmd2' filedumper {} \;
Jeśli nie masz nic przeciwko tworzeniu skryptu wykonującego polecenia cmd1 i cmd2, to jest to po prostu:
find . -exec myscript {} \;
lub
find . -exec myscript {} +
Posługiwać się \; lub + w zależności od tego, czy myscript może obsługiwać więcej niż jeden plik na raz (robi się włochaty, jeśli w nazwach plików są spacje itp.).
Z mojego doświadczenia wynika, że zapisywanie tego, co robiłeś w skrypcie, prawie zawsze było tego warte. Jeśli musisz to zrobić raz, musisz to zrobić ponownie.
Ale fajną sztuczką jest umieszczenie znaleziska w skrypcie:
if [ $# -gt 0 ]; then
for each; do
touch $each
done
else
find . -exec $0 {} +
fi
Następnie myscript działa na wszystkich plikach, które podajesz jako argumenty, ale jeśli nie podasz żadnych argumentów, uruchamia find z bieżącego katalogu, a następnie wywołuje się na znalezionych plikach. Pomija to fakt, że find -exec nie może wywoływać funkcji powłoki zdefiniowanych w skrypcie.
Próbowałem obu poprzednich rozwiązań bez większego szczęścia. Ten działał dla mnie ładnie:
$ for i in `find . -exec echo {} \;`; do cmd1 $i; cmd2 $i; done
spróbuj polecenie:
sudo find -name "*[!0-9][1-9].txt" -exec chmod 744 * {} \; -a -exec ls -l {} \; | sort | parallel ls -l
*
W -exec
części wzrośnie do wszystkich plików w bieżącym katalogu. Zwłaszcza gdy działa jako sudo
.
-o
.