Wie kann ich nur Dateinamen aus dem Befehl find zurückgeben?

13

Ich versuche, eine Liste nur der Dateinamen (ohne den Rest des Pfads) zu erhalten, wenn der Befehl find von einem Terminal ausgeführt wird. Wie mache ich das auf dem Mac?

Blaubeerfelder
quelle

Antworten:

17

Mit Basisname:

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

Paulo Almeida
quelle
Was sind geschweifte Klammern?
nullpotent
basename wird einmal für jede gefundene Datei ausgeführt, die mit {} gekennzeichnet ist.
Ярослав Рахматуллин
was ist der Mittelwert von \ und; ?
Neouyghur
@neouyghur ;beendet die -execAktion. Das \ wird benötigt, weil ;auch die Schale eine besondere Bedeutung hat.
8bittree
6

Evilsoup erwähnte, dass das, was gepostet wurde, für Dateinamen mit Zwischenraum nicht funktioniert. Also können Sie stattdessen Folgendes verwenden:

find . -type f -print0 | while IFS= read -r -d '' filename; do echo ${filename##*/}; done
Nerdwaller
quelle
Dies wird auf Dateien mit Leerzeichen in ihren Namen brechen (siehe Analyse von ls in
Gregs
+1 für Geschwindigkeit. Ich weiß nicht, ob ich etwas falsch gemacht habe, aber dieser Vorgang dauerte 1 Sekunde auf meinem $ HOME, während alle anderen ungefähr 10 Sekunden dauerten. Natürlich würde ich mehr als 10 Sekunden brauchen, um dies nachzuschlagen und es zu tippen.
Paulo Almeida
2

Mit GNU find können Sie Folgendes tun:

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

Dies ist wahrscheinlich auch in OS X einen Versuch wert.

Ярослав Рахматуллин
quelle
2
-printfwird unter OS X BSD nicht unterstützt find.
Daniel Beck
1
Auch -printfhat wenig Bezug auf das C printfoder das POSIX - Shell - Dienstprogramm printf. Die Verwendung dieses historischen Funktionsnamens für etwas anderes wird sehr wenig berücksichtigt. Die konservativen BSD-Leute sehen das wahrscheinlich genauso, also werden wir wahrscheinlich keinen Klon -printfim BSD-Fund unter diesem Namen sehen.
Kaz
Ich bin nicht einverstanden, dass die Verwendung eines vertrauten Funktionsnamens zur Ausführung einer ähnlichen Aufgabe in einem anderen Kontext als unzureichend angesehen wird. Warum BSD es wahrscheinlich nie unterstützen wird, ist eine andere Sache.
Ярослав Рахматуллин
2

Es gibt eine bessere Möglichkeit, alles außer dem letzten Teil eines Dateipfads zu entfernen. mit awk. Es ist besser, weil awk nicht für jede Datei einmal ausgeführt wird. In einigen Fällen ist das wichtig.

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

Wir suchen nur nach Dateien in ~ / tmp und erhalten eine Liste, in der jeder Eintrag durch Schrägstriche getrennt ist. Daher verwenden wir einen Schrägstrich als Feldtrennzeichen (-F /) und geben den Feldparameter ($ 1 .. $ 9) aus, der dem letzten Feld ($ NF) entspricht.

Ярослав Рахматуллин
quelle
Dies ist die schnellste, die ich getestet habe.
Paulo Almeida
Ich habe Cygwin in letzter Zeit verwendet und das Erstellen eines Prozesses in Windows ist super teuer ...
Ярослав Рахматуллин
2

EDIT :

Verwenden von sed:

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

Verwenden Sie den Befehl xargs , wie in der Antwort von @nerdwaller erwähnt

$ find . -type f -print0 | xargs --null -n1 basename
stderr
quelle
1
Danke, dass du darauf hingewiesen hast, +1, ich habe xargs nicht viel benutzt ... Auf jeden Fall, da du einige Zeichen von meinem Befehl gestrichen hast.
Nerdwaller
Dieser bricht ab, wenn Dateien Leerzeichen enthalten. Zumindest in einem kurzen Test funktioniert das so:find . -type f -print0| xargs --null -n1 basename
Paulo Almeida
Weder von --nullnoch -n1Optionen sind für OSX verfügbar
Valeriy Van
1

Was ist damit:

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

Vorteil: Es wird nur genau ein zusätzlicher Prozess erzeugt, nicht einer für jedes Ergebnis.

David Foerster
quelle
0

Sie können shaus der find- -execOption heraus aufrufen und unnötige Pipes vermeiden. Dies hat auch den Vorteil, dass Sie sich keine Gedanken über lustige Dateinamen (Leerzeichen, Zeilenumbrüche usw.) machen müssen:

find . -type f -exec sh -c 'echo "${0##*/}"' {} \;
Übelsuppe
quelle