Jak wypisać nazwę pliku w poleceniu find podczas używania -exec?

33

Używam następującego wiersza, aby znaleźć wszystkie podkatalogi PWD i uruchomić svnadmin verifyw każdym katalogu (już wiem, że są to repozytoria Subversion)

find ./* -maxdepth 0 -exec svnadmin verify {} \;

Działa to dobrze, poza tym, że dane wyjściowe wyglądają tak:

* Verifying repository metadata ...
* Verifying metadata at revision 1 ...
* Verifying metadata at revision 2 ...
* Verifying metadata at revision 4 ...
* Verifying metadata at revision 5 ...
* Verifying metadata at revision 6 ...
* Verifying metadata at revision 9 ...
* Verifying metadata at revision 10 ...
* Verifying metadata at revision 12 ...
* Verifying metadata at revision 14 ...
* Verifying metadata at revision 15 ...
* Verifying metadata at revision 18 ...
* Verifying metadata at revision 20 ...
* Verifying metadata at revision 22 ...
* Verified revision 0.
* Verified revision 1.
* Verified revision 2.
* Verified revision 3.
* Verified revision 4.
* Verified revision 5.
* Verified revision 6.
* Verified revision 7.
* Verified revision 8.
* Verified revision 9.
* Verified revision 10.
* Verified revision 11.
* Verified revision 12.
* Verified revision 13.
* Verified revision 14.
* Verified revision 15.
* Verified revision 16.
* Verified revision 17.
* Verified revision 18.
* Verified revision 19.
* Verified revision 20.
* Verified revision 21.
* Verified revision 22.
* Verified revision 23.
* Verified revision 0.
* Verifying repository metadata ...
* Verifying metadata at revision 4 ...
* Verifying metadata at revision 5 ...
* Verifying metadata at revision 6 ...
* Verifying metadata at revision 7 ...
* Verifying metadata at revision 9 ...
* Verified revision 0.
* Verified revision 1.
* Verified revision 2.
* Verified revision 3.
* Verified revision 4.
* Verified revision 5.
* Verified revision 6.
* Verified revision 7.
* Verified revision 8.
* Verified revision 9.

Naprawdę chciałbym findwydrukować nazwę pliku przed wykonaniem svnadmin verifypolecenia, aby ułatwić logowanie.

Próbowałem się trochę lswcisnąć, ale wytrząsałem, jak mam to zrobić (najlepiej po prostu)?

Arroniczny
źródło

Odpowiedzi:

36

po prostu dodaj -printfwcześniej opcję

find -printf '%p' -exec command \;
Fiximan
źródło
4
Cudownie, zmieniłem '%p'na, '%p\n'aby nazwa poprzedza weryfikację wyjścia we własnej linii.
Arroniczny
17
@Arroniczny, jeśli tego chcesz, możesz zastąpić (sformatowany) -printf '%p\n'prostszym-print
steeldriver
4
find -name <a_name> -print -exec command {} \;
toliveira
14

Jeśli nie chcesz się powtarzać, nie ma sensu używać find. O wiele łatwiej jest to zrobić bezpośrednio w powłoce:

for d in */; do echo "$d"; svnadmin verify "$d"; done

for d in */Znajdzie wszystkie katalogi (The */, zapewnia jedynie katalogów i żadne pliki nie znajdują); echo "$d"wypisze nazwę katalogu użytkownika; svnadmin verify "$d"sprawdzi katalog.

Można to uruchomić bezpośrednio z wiersza poleceń lub ze skryptu bez zmiany formatu.

terdon
źródło
1
To wygląda na lepszy sposób na osiągnięcie mojego celu, ale musiałem udzielić odpowiedzi Fiximanowi tylko dlatego, że mój tytuł i odniesienie do pytania findtak bardzo. Dzięki za poszerzenie mojej wiedzy!
Arroniczny
Wymaga to użycia glob. Globbing jest zdecydowanie użyteczny i potężny, ale z mojego osobistego doświadczenia składnia jest trudniejsza do skonfigurowania i często wymaga innych rzeczy, takich jak dotglobiw globstarbash, co tworzy dłuższy, bardziej skomplikowany skrypt. Zwykle zapisuję globusy do dużych, skomplikowanych zadań, podczas gdy findskładnia jest łatwiejsza do zebrania w locie, po prostu łącząc kilka filtrów i poleceń w jedno-liniowy.
user5359531
@ user5359531 ani globstar, ani dotglob (chyba że wiesz, że masz ukryte pliki i naprawdę ich potrzebujesz) nie są tutaj potrzebne. To oczywiście kwestia opinii, ale jesteś pierwszą osobą, jaką spotkałem, która uważa raczej tępy format za findprostszy. Zawsze wolę globusy, findponieważ nie tylko uważam je za znacznie prostsze, ale są również bezpieczniejsze, gdy mamy do czynienia z dowolnymi nazwami plików przekazywanymi do innych programów.
terdon
6
find ./* -maxdepth 0 -type d -exec bash -c 'echo "{}"; svnadmin verify "{}"' \;

Dodałem, -type djeśli to tylko katalogi.

7171u
źródło
Chciałbym zacytować {}, przynajmniej wsvnadmin verify {}
Kos
Dzięki za szybką odpowiedź. Czy więc w tym poleceniu -execspawn jest powłoką potomną, w której uruchamiane są 2 polecenia, używając ;jako końca linii?
Arroniczny
5

Spróbuj tego:

for f in * ; do echo  -n "${f}:"; svnadmin verify "${f}"; done

Jeśli chcesz tylko katalogów (dzięki Uwaga @kos):

for f in */ ; do echo  -n "${f}:"; svnadmin verify "${f}"; done
Maythux
źródło
Fajnie, ale to przetworzy również pliki: for f in */przetworzy tylko katalogi
Kos
Czy to zadziała tylko w skrypcie? Czy mogę wydać go w wierszu polecenia?
Arroniczny
1
@Arronical będzie również działał jako linia poleceń
Maythux,
2
  • Posługiwać się . -maxdepth 1 zamiast ./*, potrzebujesz tylko pierwszego poziomu w strukturze folderów
  • Posługiwać się -type d , potrzebujesz tylko folderów
  • Posługiwać się ! -name "." , nie potrzebujesz.
  • Posługiwać się -exec aby uruchomić powłokę
  • Posługiwać się sh -c do uruchamiania poleceń wewnątrz powłoki

Twoje polecenie

find . -maxdepth 1 -type d ! -name "." -exec sh -c 'echo "{}"; svnadmin verify "{}"' \;

lub krócej

  • Użyj, -prunejeśli plik jest katalogiem, nie schodź do niego

Twoje polecenie

find . -mindepth 1 -prune -exec sh -c 'echo "{}"; svnadmin verify "{}"' \; 
AB
źródło
-prunewygląda ciekawie. Kiedyś ./* -maxdepth 0unikałem powrotu .z polecenia find. Nie powoduje to żadnego krytycznego błędu, ale wolę nie mieć tego w swoich wynikach.
Arronical
1

findma flagi opcji do drukowania, które są już wspomniane w innych odpowiedziach. Jeśli spojrzymy na problem z perspektywy wykonywania wielu poleceń dla tego samego aktualnie przetwarzanego pliku, findpozwala to na użycie wielu -execinstrukcji. Oznacza to, że możemy zdecydować się na użycie:

find ./* -maxdepth 0 -exec echo {} \; -exec svnadmin verify {} \; 

Ponownie należy pamiętać, że to podejście ma zastosowanie nie tylko do drukowania echo, printflub innych mediów, ale także innych poleceń.

Sergiy Kolodyazhnyy
źródło
0

Przydatne może być przesłanie danych findwyjściowych do readpętli:

find . | while read d; do echo "=== ${d}: ==="; svnadmin verify ${d}; done

Pozwala na wykonanie bardziej skomplikowanej, złożonej sekwencji poleceń z nazwami plików zwracanymi przez find, jak w tym fantazyjnym lsprzykładzie:

find . | while read f; do echo ${f} | figlet -k; done
Ves
źródło
-1

Spowoduje to wydrukowanie rekursywnie nazwy i zawartości tylko plików.

find . -type f -printf '\n\n%p:\n' -exec cat {} \;
Prashant Adlinge
źródło