Verzeichnis in find ausschließen

11

Wie finde ich jede Datei und jedes Verzeichnis, die einem Muster entsprechen, mit Ausnahme eines Verzeichnisses mit find?

Angenommen, ich habe die folgende Dateistruktur.

.
  foo-exclude-me /
    foo.txt
  foo-exclude-me-not /
    foo.txt
  Bar/
    foo.txt
    foobar /
      bar.txt
      foofoo.txt

Wie würde ich die folgende Ausgabe erhalten mit find:

./bar/foo.txt
./bar/foobar
./bar/foobar/foofoo.txt
./foo-exclude-me-not
./foo-exclude-me-not/foo.txt

Ich habe versucht, beide folgenden Befehle zu verwenden:

finden . -name 'foo-exclude-me' -prune -o -name 'foo *'
finden . -name 'foo *' \! -path './foo-exclude-me/*'

aber beide erwidern dies:

./bar/foo.txt
./bar/foobar
./bar/foobar/foofoo.txt
./foo-exclude-me # << this should be excluded
./foo-exclude-me-not
./foo-exclude-me-not/foo.txt

Wie kann ich das foo-exclude-meVerzeichnis ordnungsgemäß ausschließen ?

Tyilo
quelle
Versuchen Sie es mit foo-exclude-meanstelle von ./foo-exclude-me. Versuchen Sie auch, -printam Ende des Befehls anzuhängen.
n0pe
@ MaxMackie perfekt :)
Tyilo
Es hat es behoben? Welches Update hat bei Ihnen funktioniert? Ich kann es in eine Antwort anstelle eines Kommentars setzen.
n0pe
@ MaxMackie mit beiden -printund foo-exclude-meanstelle von ./foo-exclude-me.
Tyilo
Genial, sieht so aus, als hätte Gilles mich geschlagen :)
n0pe

Antworten:

11
find . -name 'foo-exclude-me' -prune -o -name 'foo*' -print

Mit no -printgilt die implizite Standardaktion für jede Übereinstimmung, auch für beschnittene. Das explizite -printgilt nur unter den angegebenen Bedingungen, die sich -name 'foo*'nur im else-Zweig von befinden -name 'foo-exclude-me'.

Verwenden -printSie im Allgemeinen eine explizite Option, wenn Sie etwas Komplexeres als eine Konjunktion von Prädikaten ausführen.

Ihr zweiter Versuch mit ! -path './foo-exclude-me/*'hat nicht funktioniert, weil er ./foo-exclude-menicht übereinstimmt ./foo-exclude-me/*(kein Nachlauf /). Hinzufügen ! -path ./foo-exclude-mewürde funktionieren.

Gilles 'SO - hör auf böse zu sein'
quelle
-2
-bash-4.1 $ find. -exec ls -l {} + -name 'a.out' -prune -o -name '*' -exec rm -f {} + -exec ls -l {} +

-rw-r - r--. 1 oradba dba 499 Jan 18 19:30 ./a.out
-rw-r - r--. 1 oradba dba 499 Jan 18 20:59 ./b.out
-rw-r - r--. 1 oradba dba 499 Jan 18 20:59 ./c.out
-rw-r - r--. 1 oradba dba 499 Jan 18 20:59 ./d.out

.:
insgesamt 16
-rw-r - r--. 1 oradba dba 499 Jan 18 19:30 a.out
-rw-r - r--. 1 oradba dba 499 Jan 18 20:59 b.out
-rw-r - r--. 1 oradba dba 499 Jan 18 20:59 c.out
-rw-r - r--. 1 oradba dba 499 Jan 18 20:59 d.out
rm: `. 'kann nicht entfernt werden: Ist ein Verzeichnis
ls: kann nicht auf ./b.out zugreifen: Keine solche Datei oder kein solches Verzeichnis
ls: kann nicht auf ./d.out zugreifen: Keine solche Datei oder kein solches Verzeichnis
ls: kann nicht auf ./c.out zugreifen: Keine solche Datei oder kein solches Verzeichnis
.:
insgesamt 4
-rw-r - r--. 1 oradba dba 499 Jan 18 19:30 a.out

user211226
quelle
Verwendet die Prune-Option, um a.out zu überspringen und funktioniert einwandfrei
art.s
Sie erklären absolut nicht, warum dies -prunerelevant ist. -pruneist eine der find-print
kompliziertesten
-prune True; Wenn es sich bei der Datei um ein Verzeichnis handelt, steigen Sie nicht in dieses Verzeichnis ab. - Es wird sich also nicht als Schutz in die Verzeichnisse einarbeiten. - art.s
user211226