Wie markiere ich Verzeichnisse in der Ausgabe des Befehls „find“?

Wie markiere ich Verzeichnisse in der Ausgabe des Befehls „find“?

Beispielsweise suche ich nach Dateien und Verzeichnissen in einem Verzeichnis:

ubuntu@example:/etc/letsencrypt$ sudo find . -name example.com*
./archive/example.com
./renewal/example.com.conf
./live/example.com
ubuntu@example:/etc/letsencrypt$ 

Wie kann ich das markieren ./archive/example.comund ./live/example.comsind die Verzeichnisse in der Ausgabe oben?

Antwort1

Drucken Sie den Dateityp zusammen mit dem Namen mit -printf "%y %p\n":

$ sudo find . -name 'example.com*' -printf "%y %p\n"
d ./archive/example.com
f ./renewal/example.com.conf
d ./live/example.com

Die Verwendung -printfsetzt GNU voraus find(die gängigste findImplementierung auf Linux-Systemen).

Antwort2

Zweimal finden:

echo 'directories'
find . -name 'example.com*'   -type d

echo 'non-directories'
find . -name 'example.com*' ! -type d

Beachten Sie auch die Anführungszeichen des Musters, das für den Namenstest verwendet wird. Ohne Anführungszeichen würde die Shell versuchen, die Zeichenfolge mit Namen im aktuellen Verzeichnis abzugleichen, bevor sie aufruft find. Wenn die failglobShell-Option in der Shell gesetzt war bashoder wenn die NOMATCHShell-Option in zshnicht aufgehoben war, würde ein nicht in Anführungszeichen gesetztes Globbing-Muster, das mit nichts übereinstimmt, einen Fehler von der Shell erzeugen und findüberhaupt nicht aufgerufen werden.


Alternativ können Sie auch einfach einen Schrägstrich am Ende des Verzeichnispfadnamens ausgeben (so ls -pwürden Verzeichnisse dargestellt):

find . -name 'example.com*' \( -type d -exec printf '%s/\n' {} \; -o -print \)

Der obige findBefehl prüft zunächst, ob der Name korrekt ist. Wenn dies der Fall ist und es sich um ein Verzeichnis handelt, wird printfder Pfadname des Verzeichnisses mit einem Schrägstrich am Ende ausgegeben. Wenn dies nicht der Fall ist, -printwird der Pfadname einfach so ausgegeben, wie er ist.

Mit GNU könnte finddas -exec printf '%s/\n' {} \;Bit durch ersetzt werden -printf '%p/\n'.

Mit Standard findkönnten Sie -exec printf '%s/\n' {} +das externe Dienstprogramm auch so wenig wie möglich aufrufen printf, aber das würde bedeuten, dass Verzeichnisse wahrscheinlich zuletzt oder zumindest stapelweise ausgegeben würden.


Eine weitere Alternative besteht darin, tatsächlich zu verwenden, ls -pum Verzeichnisse von anderen Dateitypen zu unterscheiden. Bei Verwendung ls -pwürde ein Verzeichnis mit einem abschließenden Zeichen aufgelistet /, genau wie oben.

find . -name 'example.com*' -exec ls -f -d -p {} +

Ich verwende -fhier, um zu vermeiden, dass lsdie Ausgabe sortiert wird, und -dum die Auflistung derInhaltvon Verzeichnissen.

Sie können ls -Fstatt ls -pauch verwendenandereMarkierungen für andere Dateitypen als Verzeichnisse. Ausführbare Dateien würden beispielsweise mit *und symbolische Links mit versehen @.

Sowohl -pals auch -F(und -fund -d) sind Standardoptionen für das lsDienstprogramm.

Antwort3

Sie können filees so verwenden:

sudo find . -name "example.com*" -print0 | xargs  -0 sudo file

Beispielausgabe:

$ sudo find .  -name "example.com*"   -print0 | xargs  -0 sudo file
./example.com. big file: ASCII text
./example.com-dir:       directory
./example.com:           empty

Antwort4

Wenn Sie eine portablere Option wünschen, die mit *nix-Varianten ohne die GNU-Option funktioniert -printf(z. B. macOS), können Sie am Ende der Verzeichnispfade wie lsfolgt einen Schrägstrich hinzufügen:

find . -name "example.com*" -exec ls -dF {} \;

Beispiel:

$ sudo find . -name "example.com*" -exec ls -dF {} \;
./archive/example.com/
./renewal/example.com.conf
./live/example.com/

Dies liegt zufällig auch in einem Format vor, das für die weitere Weiterleitung an weitere Unix-Befehle besser geeignet ist.

verwandte Informationen