Wie lasse ich die meisten, aber nicht alle symbolischen Links finden?

10

Mein Betriebssystem und mein Home-Verzeichnis befinden sich auf einer SSD. Ich speichere einige große Dateien auf einer Festplatte und verweise von meinem Ausgangsverzeichnis auf die Festplatte (z. B. ~ / Videos / Films ist ein Symlink zu / mnt / hdd / Films). Ich habe auch eine Reihe von Wine-Präfixen, von denen jedes dosdevices / z: symlinked to / hat.

Wenn ich also find ohne -L verwendet habe, wird alles fehlen, was sich auf der Festplatte befindet. Wenn ich jedoch find mit -L verwende, endet es aufgrund von Wines Symlink zu / in einer Schleife.

Gibt es eine sinnvolle Möglichkeit, dies zu beheben, um Suchen dort zu finden, wo ich sie haben möchte? Intuitiv möchte ich etwas in der Art von "Follow Symlinks, es sei denn, sie befinden sich in einem Verzeichnis namens dosdevices". "Folgen Sie Symlinks, die sich auf etwas auf der Festplatte befinden" würde ebenfalls funktionieren.

Mark Raymond
quelle

Antworten:

11

Die -pruneprimäre findAnweisung weist an, nicht unter einem Verzeichnis zu rekursieren.

find -L -path ~/.wine/dosdevices -prune -o -type f -name 'My Favorite Movie.*' -print

Wenn Sie -lnamein Ihrem Zustand verwenden möchten , können Sie die -LOption nicht verwenden , da -Ldie meisten Prädikate auf das Ziel des Links einwirken, einschließlich -lname. In diesem Fall würde ich empfehlen, sowohl Ihr Home-Verzeichnis als auch das Festplattenstammverzeichnis als Stammverzeichnis Ihrer Suche zu verwenden.

find ~ /mnt/hdd -xtype f -name 'My Favorite Movie.*'

Sie können find ~ -type l …eine Liste symbolischer Links erstellen und diese als zusätzliche Wurzeln verwenden.

( IFS=$'\n'; set -f;
  find ~ $(find ~ -type l -lname '/mnt/hdd/*') \
       -xtype f -name 'My Favorite Movie.*' )

Wenn Sie wirklich unter symbolischen Links wiederkehren möchten, können Sie bestimmte symbolische Links nach Ziel anstatt nach Namen ausschließen. Auf diese Weise können Sie jedoch nur eine endliche Liste ausschließen, kein Muster oder Teilbaum.

find -L \( -samefile /exclude/this -o -samefile ~/and/that \) -prune -o \
     -type f -name 'My Favorite Movie.*' -print

Sie können andere Kriterien verwenden, z. B. ! -writable(Dateien, für die Sie keine Schreibberechtigung haben), aber ich glaube nicht, dass GNU find nur dann eine Möglichkeit bietet, unter symbolischen Links zu rekursieren, wenn ihr Zieltext mit einem bestimmten Ausdruck übereinstimmt.

Sie können einen findBefehl erstellen , der fast das tut, was Sie wollen, außer nicht genügend symbolische Links auszuschließen, find2perl ausführen , um die Abfrage in ein Perl-Skript zu konvertieren, und das Perl-Skript ein wenig optimieren. Es gibt viele Schalter von GNU find, die find2perl jedoch nicht erkennt.

Gilles 'SO - hör auf böse zu sein'
quelle
Vielen Dank! -pruneist genau das, wonach ich gesucht habe. Ich habe festgestellt, dass find ~ \( -lname ~ -o -lname ~/\* -o -lname / \) -xtype dalle Symlinks aufgelistet sind, denen ich nicht folgen möchte. Ich versuche jetzt, einen Weg zu finden, diese Abfrage zum Beschneiden zu verwenden.
Mark Raymond
@ MarkRaymond Das allgemeine Prinzip ist find ~ <negative criteria> -prune -o <positive criteria> -print, alsofind ~ \( -lname ~ -o -lname ~/\* -o -lname / \) -xtype d -prune -o <whatever it is you want> -print
Gilles 'SO - hör auf böse zu sein'
@Giles - das funktioniert gut ohne -L, aber sobald ich -L hinzufüge, funktionieren die Ausdrücke -lname nicht mehr (wie die Manpage sagt, werden sie nicht). Im Grunde brauche ich dann einige Bedingungen, um Symlinks zu folgen und andere nicht!
Mark Raymond
Ich kann mir keine Möglichkeit vorstellen, genau das zu tun, was Sie mit find wollen. Siehe meine Bearbeitung für einige Annäherungen.
Gilles 'SO - hör auf böse zu sein'
1

Um ALLE Links zu durchsuchen, hat dies bei mir funktioniert:

find -L . -name \*.txt
Jim
quelle
0

Wie viele Symlinks zu Festplatten haben Sie? Wenn es nicht zu viele sind, besteht eine Lösung darin, "-L" nicht zu verwenden, während Sie explizit die Symlinks angeben, denen Sie in der Befehlszeile find folgen möchten. Etwas wie:

find .  ~/Videos/Films -name '*file I want*' ...

Dadurch werden das aktuelle Verzeichnis (".") Sowie der Symlink "~ / Videos / Films" durchsucht, jedoch keine anderen Symlinks angezeigt.

John1024
quelle
0

Eine andere Lösung, die das Problem umgeht (zumindest für meinen Fall), besteht darin, Bindungs-Mounts anstelle symbolischer Links für die Verzeichnisse auf der Festplatte zu verwenden. Dies erfolgt durch Hinzufügen von Einträgen /etc/fstabwie folgt :

/mnt/hdd/Films /home/mark/Videos/Films none bind 0 0

Mark Raymond
quelle