So finden Sie sowohl symbolische Links als auch Verzeichnisse mit dem Befehl „Find“

So finden Sie sowohl symbolische Links als auch Verzeichnisse mit dem Befehl „Find“

Ich hasse den Find-Befehl und möchte das einfach nur loswerden. Das mit Abstand am schlechtesten konzipierte CLI-Tool in der Linux-Welt, das ich seit vielen Jahren verwende.

Es stellt sich heraus, dass der folgende Befehl nichts zurückgibt:

cd "$go_proj_path_root" && cd .. && find "$go_proj_path_root" -mindepth 1 -maxdepth 1 -type l -type d

es gibt nichts zurück, weil sich -type l und -type d offenbar widersprechen? Wenn ich einfach verwende:

cd "$go_proj_path_root" && cd .. && find "$go_proj_path_root" -mindepth 1 -maxdepth 1 -type l 

dann findet es die Symlinks im Verzeichnis. Gibt es eine Möglichkeit, sowohl Verzeichnisse als auch Symlinks mit demselben Befehl zu finden? Wirklich schrecklich, find! Wenn ich nur Symlinks wollte, würde ich einfach -type l..wtf verwenden.

Antwort1

Ja, -type l -type dbedeutet „wenn die Datei ein Verzeichnis istUndein symbolischer Link". Was Sie vielleicht versuchen möchten, ist \( -type l -o -type d \).

Beachten Sie auch, dass dies cdnicht erforderlich ist (es sei denn, Sie verwenden es, um zu überprüfen, ob es $go_proj_path_rootsich um ein Verzeichnis handelt, auf das Sie Zugriff haben):

find "$go_proj_path_root" -mindepth 1 -maxdepth 1 \( -type l -o -type d \) -print

Da Sie anscheinend nur an den Dateien in einem einzigen Verzeichnis interessiert sind, gehen Sie alternativ wie folgt vor:

shopt -s nullglob dotglob
for name in "$go_proj_path_root"/*; do
    if [ -d "$name" ] || [ -L "$name" ]; then
        printf '%s\n' "$name"
    fi
done

Mit der zshShell:

print -rC1 -- $go_proj_path_root/*(ND/) $go_proj_path_root/*(ND@)

... wobei die Glob-Qualifizierer /und @bewirken, dass das vorangehende Globbing-Muster nur Verzeichnisse bzw. symbolische Links abgleicht, und NDhat dieselben Auswirkungen wie das Setzen der Shell nullglob- dotglobOptionen und in bash(auf nichts erweitern, wenn keine Übereinstimmung vorliegt, und auch mit versteckten Namen übereinstimmen). Das print -rC1gibt die resultierenden Namen in einer einzelnen Spalte aus ( -rvermeidet die Interpretation von Backslash-Sequenzen).

Antwort2

Wenn Sie Suchkriterien hinzufügen, werden diese standardmäßig alle angewendet:

find "$go_proj_path_root" -mindepth 1 -maxdepth 1 -type l -type d

fragt nach Dateien, die zugleich Links und Verzeichnisse sind.

Sie müssen „oder“ verwenden:

find "$go_proj_path_root" -mindepth 1 -maxdepth 1 -type l -o -type d

Obwohl es hier nicht notwendig ist, ist es eine gute Idee, sich anzugewöhnen, Klammern um folgendes zu verwenden -o:

find "$go_proj_path_root" -mindepth 1 -maxdepth 1 \( -type l -o -type d \)

(escaped, sodass sie für die Shell nichts bedeuten).

verwandte Informationen