Czasami widzę następujące polecenie:
find . -name * -exec ls -a {} \;
Zostałem poproszony o wykonanie tego.
Co to {} \;
znaczy tutaj?
command-line
find
codeofnode
źródło
źródło
-name *
jest zbędny.-name *
jest gorszy niż zbędny. Ponieważ*
nie jest cytowany, powłoka rozwija go do listy nazw plików w bieżącym folderze, a spacje są niepoprawnie traktowane, co prowadzi do nieoczekiwanych wyników lub komunikatu o błędzie. Dodatkowofind
ma wiele funkcji, jedną z nich jest wyświetlanie listy plików; pozwala to uniknąć konieczności używania-exec
. Np. Możesz użyćfind . -print
lubfind . -ls
. Wreszcie, istnieją dwa sposoby, aby uciec średnik: albo jak to było z ukośnik,\;
lub podając:';'
. Używaj tego, z czym czujesz się bardziej komfortowo.Odpowiedzi:
Jeśli uruchamiasz
find
zexec
,{}
rozwija się do nazwy pliku każdego znalezionego pliku lub katalogufind
(tak, żels
w twoim przykładzie dostaje się każdy znaleziony plik jako argument - pamiętaj, że wywołuje onls
dowolną inną komendę podaną raz dla każdego znalezionego pliku).Średnik
;
kończy polecenie wykonane przezexec
. Trzeba go uciec,\
aby pocisk, który w nim biegniefind
, nie traktował go jako własnego znaku specjalnego, lecz przekazał gofind
.Więcej informacji znajdziesz w tym artykule .
Ponadto,
find
zapewnia pewną optymalizację zexec cmd {} +
- kiedy prowadzony tak,find
Dokleja znaleźć pliki na końcu polecenia, a nie powołując go raz na plik (tak, że polecenie jest uruchamiane tylko raz, jeśli to możliwe).Różnica w zachowaniu (jeśli nie pod względem wydajności) jest łatwo zauważalna, jeśli jest uruchamiana
ls
npZakładając, że masz kilka
jpg
plików (z wystarczająco krótkimi ścieżkami ), wynikiem jest jeden wiersz na plik w pierwszym przypadku i standardowels
zachowanie wyświetlania plików w kolumnach dla tego drugiego.źródło
\;
się+
.find . -name * | ls -a -
?find
. Ponadto dane wyjściowels
w tym przypadku najwyraźniej nie zależą od danych wejściowych - bez względu na to, czego używam jako filtrfind
,ls
po prostu wyświetla zawartość katalogu roboczego i to wszystko. Sprawdzić na przykładfind ~ -iname '*.jpg' -exec ls -a {} \;
vsfind ~ -iname '*.jpg' | ls -a
.echo 'foo' | ls -a
.-
w swoimls -a -
poleceniu podczas testowania tego, o co pytał @ dr-h.Z strony podręcznika dla
find
polecenia :Oto wyjaśnienie:
{}
oznacza „wynikfind
”. Jak w „cokolwiekfind
znaleziono”.find
zwraca ścieżkę szukanego pliku, prawda? Więc{}
zastępuje go; jest to symbol zastępczy dla każdego pliku, któryfind
lokalizuje polecenie (pochodzi stąd ).Ta
\;
część mówi w zasadziefind
„OK, skończyłem z poleceniem, które chciałem wykonać”.Przykład:
Powiedzmy, że jestem w katalogu pełnym
.txt
plików. Następnie uruchamiam:Pierwsza część
find . -name *.txt
zwraca listę.txt
plików. Druga część,-exec cat {} \;
wykonacat
polecenie dla każdego pliku znalezionego przezfind
, takcat file1.txt
,cat file2.txt
i tak dalej.źródło
*.txt
należy podać jako'*.txt'
. Wynika to z faktu, że jeśli.txt
w bieżącym folderze znajdują się pliki, powłoka to rozwinie, a otrzymasz nieprawidłowe wyniki lub komunikat o błędzie.find -name '*.txt' -exec cat {} \;