GNU Find schließt übergeordnete Verzeichnisse ein

GNU Find schließt übergeordnete Verzeichnisse ein

Ich versuche, GNU dazu zu bringen, Ausschlusseinträge BIS zum angegebenen Dateinamen zu finden.

Nehmen Sie diesen Beispielbaum:

./foo
./foo/another.txt
./foo/bar
./foo/bar/world
./foo/bar/world/test.txt
./foo/bar/world/hello.txt

(In den und anderen Verzeichnissen gäbe es worldnoch eine Menge anderer Dateien, deshalb suche ich nicht einfach nach hello.txt).

Ich möchte alles außer „test.txt“ und den übergeordneten Verzeichnissen abgleichen.

Die Ausgabe sollte einfach sein foo/bar/world/hello.txt.

Dieser Befehl erzeugt die richtigen Ergebnisse, ist jedoch ziemlich chaotisch und würde falsche Ergebnisse erzeugen, wenn es mehrere Verzeichnisse mit den gleichen Namen gäbe:

find * ! -name test.txt -a ! -name foo -a ! -name bar -a ! -name world

Antwort1

Geben Sie an , dass findSie nur an Dateien und nicht an Verzeichnissen interessiert sind.

find ./foo -type f ! -name test.txt

Aktualisieren:

Nehmen wir dieses etwas komplexere Beispiel an:

$ find ./foo
./foo
./foo/baz
./foo/baz/b.csv
./foo/baz/a.txt
./foo/bar
./foo/bar/c.txt
./foo/bar/world
./foo/bar/world/hello.txt
./foo/bar/world/test.txt

Wenn Ihr Ziel das Löschen von Dingen ist, müssen Sie angeben, -depthdass Dateien vor ihren Verzeichnissen angezeigt werden:

$ find ./foo -depth
./foo/baz/b.csv
./foo/baz/a.txt
./foo/baz
./foo/bar/c.txt
./foo/bar/world/hello.txt
./foo/bar/world/test.txt
./foo/bar/world
./foo/bar
./foo

Wenn Sie den Pfad kennen, den Sie behalten möchten, können wir einen regulären Ausdruck entwickeln, der mit Teilen davon übereinstimmt:

$ find ./foo -depth -regextype posix-extended -regex '^\./foo(/bar(/world(/test.txt)?)?)?'
./foo/bar/world/test.txt
./foo/bar/world
./foo/bar
./foo

Dann können wir den regulären Ausdruck einfach negieren, um das zu erhalten, was Sie entfernen möchten:

$ find ./foo -depth -regextype posix-extended ! -regex '^\./foo(/bar(/world(/test.txt)?)?)?'
./foo/baz/b.csv
./foo/baz/a.txt
./foo/baz
./foo/bar/c.txt
./foo/bar/world/hello.txt

Antwort2

Wenn Sie die genaue Tiefe des Baums kennen (d. h. Sie möchten die Dateien ab dem dritten Ordner abrufen), können Sie Folgendes verwenden:

find . -mindepth $depth ! -name test.txt

Mit Ihrer Verzeichnisstruktur erhalte ich:

$ find . -mindepth 4 ! -name test.txt
./foo/bar/world/hello.txt

Und das ist genau das, was Sie erwarten.


EDIT: das sollte besser sein (aber hässlicher!). Es findet das Verzeichnis, in dem test.txtsich befindet, und findet alle darin enthaltenen Dateien. Der Vorteil ist, dass es völlig unabhängig von den übergeordneten Pfaden ist, da es diese automatisch berechnet.

EXCLUDEFNAME="test.txt"; find $(find . -name "$EXCLUDEFNAME" -exec dirname {} \; -quit) -mindepth 1 ! -name "$EXCLUDEFNAME"

Mehrzeilig ist besser:

EXCLUDEFNAME="test.txt"
targetpath="$(find . -name "$EXCLUDEFNAME" -exec dirname {} \;)"
find "$targetpath" -mindepth 1 ! -name "$EXCLUDEFNAME"

verwandte Informationen