Der Befehl find: Die Optionen '-mindepth' stehen in Konflikt mit der Aktion '-prune'.

8

Wenn die Dateistruktur wie folgt ist:

/a/p/c/d...
/c/a/c/g/f/...
/a/c/d/e/...
...

Und ich möchte das tun:

find -mindepth 3 -type d -name p -prune -or -name c -print

Dieser Befehl bereinigt jedoch nicht das Verzeichnis 'p' und die erste Zeile wird eingeschlossen. Ich weiß, dass es eigentlich kein Konflikt ist. Aber wie kann man 'p' mit der angewendeten Mindepth beschneiden?

Bohr
quelle
Ich nehme das dund esind Dateien, keine Verzeichnisse?
Anthon

Antworten:

1

Ich denke, ich würde es so machen:

find -mindepth 3 -type d ! -path '*/p/*' -name c -print

Basierend auf dem Feedback von @StephaneChazelas glaube ich, dass diese Methode die überflüssige Suche in /p/Verzeichnissen eliminieren würde :

find -mindepth 3 -type d -path '*/p/*' -prune -o -name c -print

Einen Fund analysieren

Um Suchbefehle zu vergleichen, können Sie den Debug-Schalter hinzufügen, -D searchdamit Sie sehen können, wie sich ein bestimmter Suchvorgang im Vergleich zu einem anderen verhält.

Ich habe @StephaneChazelas 'Befehl gegen meinen ausgeführt, um zu sehen, wo die Unterschiede waren. Die 2 Befehle werden ausgeführt und ihre Ausgabe wird wie folgt ausgeführt sdiff:

$ sdiff \
<(find -D search -mindepth 3 -type d -path '*/p/*' -prune -o -name c -print 2>&1) \
<(find -D search -type d -name p -prune -o -path './*/*/*' -name c -print 2>&1)
consider_visiting (early): `.': fts_info=FTS_D , fts_level= 0   consider_visiting (early): `.': fts_info=FTS_D , fts_level= 0
consider_visiting (late): `.': fts_info=FTS_D , isdir=1 ignor | consider_visiting (late): `.': fts_info=FTS_D , isdir=1 ignor
consider_visiting (early): `./a': fts_info=FTS_D , fts_level=   consider_visiting (early): `./a': fts_info=FTS_D , fts_level=
consider_visiting (late): `./a': fts_info=FTS_D , isdir=1 ign | consider_visiting (late): `./a': fts_info=FTS_D , isdir=1 ign
consider_visiting (early): `./a/c': fts_info=FTS_D , fts_leve   consider_visiting (early): `./a/c': fts_info=FTS_D , fts_leve
consider_visiting (late): `./a/c': fts_info=FTS_D , isdir=1 i | consider_visiting (late): `./a/c': fts_info=FTS_D , isdir=1 i
consider_visiting (early): `./a/c/d': fts_info=FTS_D , fts_le   consider_visiting (early): `./a/c/d': fts_info=FTS_D , fts_le
consider_visiting (late): `./a/c/d': fts_info=FTS_D , isdir=1   consider_visiting (late): `./a/c/d': fts_info=FTS_D , isdir=1
consider_visiting (early): `./a/c/d/e': fts_info=FTS_D , fts_   consider_visiting (early): `./a/c/d/e': fts_info=FTS_D , fts_
consider_visiting (late): `./a/c/d/e': fts_info=FTS_D , isdir   consider_visiting (late): `./a/c/d/e': fts_info=FTS_D , isdir
consider_visiting (early): `./a/c/d/e': fts_info=FTS_DP, fts_   consider_visiting (early): `./a/c/d/e': fts_info=FTS_DP, fts_
consider_visiting (late): `./a/c/d/e': fts_info=FTS_DP, isdir   consider_visiting (late): `./a/c/d/e': fts_info=FTS_DP, isdir
consider_visiting (early): `./a/c/d': fts_info=FTS_DP, fts_le   consider_visiting (early): `./a/c/d': fts_info=FTS_DP, fts_le
consider_visiting (late): `./a/c/d': fts_info=FTS_DP, isdir=1   consider_visiting (late): `./a/c/d': fts_info=FTS_DP, isdir=1
consider_visiting (early): `./a/c': fts_info=FTS_DP, fts_leve   consider_visiting (early): `./a/c': fts_info=FTS_DP, fts_leve
consider_visiting (late): `./a/c': fts_info=FTS_DP, isdir=1 i   consider_visiting (late): `./a/c': fts_info=FTS_DP, isdir=1 i
consider_visiting (early): `./a/p': fts_info=FTS_D , fts_leve   consider_visiting (early): `./a/p': fts_info=FTS_D , fts_leve
consider_visiting (late): `./a/p': fts_info=FTS_D , isdir=1 i | consider_visiting (late): `./a/p': fts_info=FTS_D , isdir=1 i
consider_visiting (early): `./a/p/c': fts_info=FTS_D , fts_le | consider_visiting (early): `./a/p': fts_info=FTS_DP, fts_leve
consider_visiting (late): `./a/p/c': fts_info=FTS_D , isdir=1 <
consider_visiting (early): `./a/p/c': fts_info=FTS_DP, fts_le <
consider_visiting (late): `./a/p/c': fts_info=FTS_DP, isdir=1 <
consider_visiting (early): `./a/p': fts_info=FTS_DP, fts_leve <
consider_visiting (late): `./a/p': fts_info=FTS_DP, isdir=1 i   consider_visiting (late): `./a/p': fts_info=FTS_DP, isdir=1 i
consider_visiting (early): `./a': fts_info=FTS_DP, fts_level=   consider_visiting (early): `./a': fts_info=FTS_DP, fts_level=
consider_visiting (late): `./a': fts_info=FTS_DP, isdir=1 ign   consider_visiting (late): `./a': fts_info=FTS_DP, isdir=1 ign
consider_visiting (early): `./c': fts_info=FTS_D , fts_level=   consider_visiting (early): `./c': fts_info=FTS_D , fts_level=
consider_visiting (late): `./c': fts_info=FTS_D , isdir=1 ign | consider_visiting (late): `./c': fts_info=FTS_D , isdir=1 ign
consider_visiting (early): `./c/a': fts_info=FTS_D , fts_leve   consider_visiting (early): `./c/a': fts_info=FTS_D , fts_leve
consider_visiting (late): `./c/a': fts_info=FTS_D , isdir=1 i | consider_visiting (late): `./c/a': fts_info=FTS_D , isdir=1 i
consider_visiting (early): `./c/a/c': fts_info=FTS_D , fts_le   consider_visiting (early): `./c/a/c': fts_info=FTS_D , fts_le
consider_visiting (late): `./c/a/c': fts_info=FTS_D , isdir=1   consider_visiting (late): `./c/a/c': fts_info=FTS_D , isdir=1
consider_visiting (early): `./c/a/c/g': fts_info=FTS_D , fts_   consider_visiting (early): `./c/a/c/g': fts_info=FTS_D , fts_
consider_visiting (late): `./c/a/c/g': fts_info=FTS_D , isdir   consider_visiting (late): `./c/a/c/g': fts_info=FTS_D , isdir
consider_visiting (early): `./c/a/c/g/f': fts_info=FTS_D , ft   consider_visiting (early): `./c/a/c/g/f': fts_info=FTS_D , ft
consider_visiting (late): `./c/a/c/g/f': fts_info=FTS_D , isd   consider_visiting (late): `./c/a/c/g/f': fts_info=FTS_D , isd
consider_visiting (early): `./c/a/c/g/f': fts_info=FTS_DP, ft   consider_visiting (early): `./c/a/c/g/f': fts_info=FTS_DP, ft
consider_visiting (late): `./c/a/c/g/f': fts_info=FTS_DP, isd   consider_visiting (late): `./c/a/c/g/f': fts_info=FTS_DP, isd
consider_visiting (early): `./c/a/c/g': fts_info=FTS_DP, fts_   consider_visiting (early): `./c/a/c/g': fts_info=FTS_DP, fts_
consider_visiting (late): `./c/a/c/g': fts_info=FTS_DP, isdir   consider_visiting (late): `./c/a/c/g': fts_info=FTS_DP, isdir
consider_visiting (early): `./c/a/c': fts_info=FTS_DP, fts_le   consider_visiting (early): `./c/a/c': fts_info=FTS_DP, fts_le
consider_visiting (late): `./c/a/c': fts_info=FTS_DP, isdir=1   consider_visiting (late): `./c/a/c': fts_info=FTS_DP, isdir=1
consider_visiting (early): `./c/a': fts_info=FTS_DP, fts_leve   consider_visiting (early): `./c/a': fts_info=FTS_DP, fts_leve
consider_visiting (late): `./c/a': fts_info=FTS_DP, isdir=1 i   consider_visiting (late): `./c/a': fts_info=FTS_DP, isdir=1 i
consider_visiting (early): `./c': fts_info=FTS_DP, fts_level=   consider_visiting (early): `./c': fts_info=FTS_DP, fts_level=
consider_visiting (late): `./c': fts_info=FTS_DP, isdir=1 ign   consider_visiting (late): `./c': fts_info=FTS_DP, isdir=1 ign
consider_visiting (early): `.': fts_info=FTS_DP, fts_level= 0   consider_visiting (early): `.': fts_info=FTS_DP, fts_level= 0
consider_visiting (late): `.': fts_info=FTS_DP, isdir=1 ignor   consider_visiting (late): `.': fts_info=FTS_DP, isdir=1 ignor
./c/a/c                             ./c/a/c

Wenn Sie bemerken, gibt es eine Lücke in Stephanes Ansatz, die meine nicht hat. Auch mit der Pflaume. Ich denke, dies zeigt, dass seine Methode zusätzliche Arbeit beim Betreten von Verzeichnissen vermeidet, die sie sonst ignorieren sollte.

slm
quelle
Das führt jedoch immer noch findzu einem Abstieg in die pVerzeichnisse.
Stéphane Chazelas
Ja, da -prunedies in dieser Situation nicht möglich ist, ist das Filtern möglicherweise die einzige verbleibende Option.
Bohr
@StephaneChazelas, würde so etwas Ihren Standpunkt ansprechen? find -mindepth 3 -type d -path '*/p/*' -prune -o -name c -print.
slm
Ja, das ist genau richtig. Ich habe vergessen, dass ich den Weg beschneiden kann! Vielen Dank! (Dies sollte zu Ihrer Antwort hinzugefügt werden.)
Bohr
@Bohr, habe es gerade aktualisiert.
slm
4

Mit FreeBSD und GNU find(einige der wenigen unterstützten Implementierungen -mindepth) -prunewürden Sie nur die pVerzeichnisse bereinigen, die sich in Tiefe 3 oder tiefer befinden. Sowohl die FreeBSD- als auch die GNU- findDokumentation machen dies deutlich (hier GNU-Dokumentation):

-- Option: -mindepth levels
    Do not apply any tests or actions at levels less than LEVELS (a
    non-negative integer).  `-mindepth 1' means process all files
    except the command line arguments.

Sie können es stattdessen immer auf die übliche Weise tun:

find . -type d -name p -prune -o -path './*/*/*' -name c -print

( -mindepthund -orsind keine Standardprädikate find, das Weglassen der Verzeichnisse ist auch nicht Standard).

Oder mit zsh:

setopt extendedglob
printf '%s\n' ^p/^p/(^p/)#c
Stéphane Chazelas
quelle
Nur neugierig, warum sagst du, dass dieser Weg der "Standard" ist? Weil Sie verwendet -ostatt -or?
slm
@slm, der letzte Satz sollte es klar machen.
Stéphane Chazelas
Ich sehe den Hinweis jetzt in der Manpage. Er besagt, dass er -ormit der -oPOSIX-Konformität identisch ist , diese jedoch nicht.
slm
0

Laut der Manpage von find:

 -prune True;  if  the  file is a directory, do not descend into it. If
        -depth is given, false; no  effect.

In Ihrem speziellen Fall würde ich also Folgendes tun:

 find a/* -mindepth 2  -type f -print

Aber natürlich gibt es nicht immer eine so einfache Lösung.

Anthon
quelle
Entschuldigung, ich sollte es klarer machen!
Bohr