find . -type f -name '*f*' | sed -r 's|/[^/]+$||' |sort |uniq
Das Obige findet alle Dateien unterhalb des aktuellen Verzeichnisses ( .
), die reguläre Dateien ( -type f
) sind und f
irgendwo in ihrem Namen ( -name '*f*'
) stehen. sed
Entfernt als Nächstes den Dateinamen und belässt nur den Verzeichnisnamen. Anschließend wird die Liste der Verzeichnisse sortiert ( sort
) und Duplikate entfernt ( uniq
).
Der sed
Befehl besteht aus einem einzelnen Ersatz. Es sucht nach Übereinstimmungen mit dem regulären Ausdruck /[^/]+$
und ersetzt alles, was damit übereinstimmt, durch nichts. Das Dollarzeichen bedeutet das Ende der Zeile. [^/]+'
bedeutet ein oder mehrere Zeichen, die keine Schrägstriche sind. Bedeutet /[^/]+$
also alle Zeichen vom letzten Schrägstrich bis zum Zeilenende. Dies entspricht also dem Dateinamen am Ende des vollständigen Pfads. Daher entfernt der Befehl sed den Dateinamen, wobei der Name des Verzeichnisses, in dem sich die Datei befand, unverändert bleibt.
Vereinfachungen
Viele moderne sort
Befehle unterstützen ein -u
Flag, das uniq
unnötig macht . Für GNU sed:
find . -type f -name '*f*' | sed -r 's|/[^/]+$||' |sort -u
Und für MacOS sed:
find . -type f -name '*f*' | sed -E 's|/[^/]+$||' |sort -u
Wenn Ihr find
Befehl dies unterstützt, ist es auch möglich, find
die Verzeichnisnamen direkt auszudrucken. Dies vermeidet die Notwendigkeit für sed
:
find . -type f -name '*f*' -printf '%h\n' | sort -u
Robustere Version (GNU-Tools erforderlich)
Die obigen Versionen werden durch Dateinamen verwechselt, die Zeilenumbrüche enthalten. Eine robustere Lösung ist das Sortieren von Zeichenfolgen mit NUL-Abschluss:
find . -type f -name '*f*' -printf '%h\0' | sort -zu | sed -z 's/$/\n/'
uniq
In die Mischung zu werfen hilft sehr, indem die wiederholten Linien, die bereits direkt nebeneinander sind, entfernt werden.find . -type f -name '*f*' -printf '%h\0' | uniq -z | sort -zu | tr '\0' '\n'
. Oder wenn Ihre Tools etwas älter sind, hat uniq möglicherweise nicht die Option -z.find . -type f -name '*f*' -printf '%h\n' | uniq | sort -u
-E
für MacOS aktualisiert .Warum versuchst du das nicht:
quelle
find
sind eigentlich recht spärlich - der-printf
Operator ist nicht angegeben. Dies funktioniert nicht mit BSDfind
. Also nicht "ganz POSIX-kompatibel". (Obwohlsort -u
in POSIX .)Es gibt im Wesentlichen 2 Methoden, die Sie verwenden können, um dies zu tun. Einer analysiert die Zeichenfolge, während der andere die einzelnen Dateien bearbeitet. Die Zeichenfolge ein Tool wie verwenden Parsen
grep
,sed
oderawk
ist offensichtlich schneller sein würde , aber hier ist ein Beispiel sowohl, als auch, wie zeigt man „Profil“ die 2 - Methoden.Beispieldaten
Für die folgenden Beispiele verwenden wir die folgenden Daten
Löschen Sie einige der
*f*
Dateien vondir1/*
:Ansatz Nr. 1 - Parsen über Zeichenfolgen
Hier werden wir die folgenden Werkzeuge verwenden,
find
,grep
, undsort
.Ansatz 2 - Analysieren mit Dateien
Dieselbe Werkzeugkette wie zuvor, außer dass wir diesmal
dirname
anstelle von verwenden werdengrep
.HINWEIS: In den obigen Beispielen wird
head -5
lediglich der Umfang der Ausgabe beschränkt, mit der wir uns in diesen Beispielen befassen. Sie werden normalerweise entfernt, um Ihre vollständige Auflistung zu erhalten!Ergebnisse vergleichen
Wir können
time
einen Blick auf die beiden Ansätze werfen.dirname
grep
Deshalb ist es immer am besten, wenn es möglich ist, mit den Saiten umzugehen.
Alternative Methoden zum Parsen von Zeichenfolgen
grep & PCRE
sed
awk
quelle
Hier ist eine, die ich nützlich finde:
quelle
Diese Antwort basiert unverschämt auf der Antwort von slm. Es war ein interessanter Ansatz, hat aber eine Einschränkung, wenn die Datei- und / oder Verzeichnisnamen Sonderzeichen (Leerzeichen, Zwischenspalte ...) enthielten. Eine gute Angewohnheit ist zu benutzen
find /somewhere -print0 | xargs -0 someprogam
.Beispieldaten
Für die folgenden Beispiele verwenden wir die folgenden Daten
Löschen Sie einige der
*f*
Dateien vondir1/*/
:Ansatz 1 - Analysieren mit Dateien
HINWEIS : In den obigen Beispielen wird
head -5
lediglich der Umfang der Ausgabe beschränkt, mit der wir uns in diesen Beispielen befassen. Sie werden normalerweise entfernt, um Ihre vollständige Auflistung zu erhalten! Ersetzenecho
Sie auch den gewünschten Befehl.quelle
Mit
zsh
:quelle