Jak zwrócić tylko nazwy plików z polecenia find?

14

Chcę uzyskać listę tylko nazw plików (bez reszty ścieżki) podczas wykonywania polecenia find z terminala. Jak to zrobić na komputerze Mac?

Blueberryfields
źródło

Odpowiedzi:

18

Z basenemame:

find . -type f -exec basename {} \;

Paulo Almeida
źródło
Do czego służą nawiasy klamrowe?
nullpotent
basename jest uruchamiany raz dla każdego znalezionego pliku, oznaczony przez {}.
Ярослав Рахматуллин
co oznacza \ i; ?
neouyghur
@neouyghur ;kończy -execdziałanie. Jest \ to potrzebne, ponieważ ;ma również specjalne znaczenie dla powłoki.
8bittree,
6

Evilsoup wspomniał, że to, co zostało opublikowane, nie działa w przypadku nazw plików z odstępami. Zamiast tego możesz użyć:

find . -type f -print0 | while IFS= read -r -d '' filename; do echo ${filename##*/}; done
nerdwaller
źródło
Spowoduje to
uszkodzenie
+1 do prędkości. Nie wiem, czy zrobiłem coś złego, ale zajęło mi to 1 sekundę na moim $ HOME, podczas gdy wszystkie inne zajęły około 10 sekund. Oczywiście potrzebowałbym więcej niż 10 sekund, aby to sprawdzić i wpisać.
Paulo Almeida
2

Za pomocą GNU find możesz:

 find ~/tmp/ -printf "%f\n"

Prawdopodobnie warto spróbować również w systemie OS X.

Ярослав Рахматуллин
źródło
2
-printfnie jest obsługiwany na BSD OS X find.
Daniel Beck
1
Ponadto, -printfma niewielki związek z printfnarzędziem powłoki C lub POSIX printf. Używanie tej historycznej nazwy funkcji do czegoś innego jest bardzo źle brane pod uwagę. Konserwatywni faceci z BSD prawdopodobnie widzą to w ten sam sposób, więc prawdopodobnie nie zobaczymy klonu -printfw znalezisku BSD pod tą nazwą.
Kaz
Nie zgadzam się z tym, że źle jest używać znanej nazwy funkcji do wykonywania podobnego zadania w innym kontekście. Dlaczego BSD prawdopodobnie nigdy nie poprze tego, to inna sprawa.
Ярослав Рахматуллин
2

Jest lepszy sposób na usunięcie wszystkiego oprócz ostatniej części ścieżki pliku; z awk. Jest lepiej, ponieważ awk nie jest uruchamiany raz dla każdego pliku. W niektórych przypadkach ma to znaczenie.

find ~/tmp/ -type f  | awk -F/ '{ print $NF }'

Szukamy tylko plików w ~ / tmp i otrzymujemy listę, w której każdy wpis jest oddzielony ukośnikami. Dlatego używamy ukośnika jako separatora pól (-F /) i wypisujemy parametr pola (1 $ .. 9 $), który odpowiada ostatniemu polu ($ NF).

Ярослав Рахматуллин
źródło
To najszybszy testowałem.
Paulo Almeida
Ostatnio korzystam z Cygwin, a tworzenie procesu w systemie Windows jest bardzo drogie ...
Ярослав Рахматуллин
2

EDYCJA :

Używanie sed:

$ find . -type f | sed 's/.*\///'

Korzystanie z polecenia xargs , jak wspomniano w odpowiedzi @nerdwaller

$ find . -type f -print0 | xargs --null -n1 basename
stderr
źródło
1
Dzięki za wskazanie tego, +1, nie używałem zbyt wiele xargs ... Zdecydowanie powinieneś, ponieważ zrzuciłeś ze mnie sporo znaków.
nerdwaller
Ten się psuje, gdy pliki mają spacje. Działa to w ten sposób, przynajmniej w szybkim teście:find . -type f -print0| xargs --null -n1 basename
Paulo Almeida,
Żadna z opcji --nullani nie -n1jest dostępna w OSX
Valeriy Van
1

A co z tym:

find … | egrep -o -e '[^/]+$'

Zaleta: spawnowany jest tylko jeden dodatkowy proces, a nie jeden dla każdego wyniku.

David Foerster
źródło
0

Możesz dzwonić shz -execopcji find i unikać używania niepotrzebnych potoków. Ma to również tę zaletę, że nie musisz się martwić o śmieszne nazwy plików (spacje, znaki nowej linii itp.):

find . -type f -exec sh -c 'echo "${0##*/}"' {} \;
zła
źródło