ubuntuusers.de

und wieder: find - diesmal: Reihenfolge der Parameter

Status: Gelöst | Ubuntu-Version: Ubuntu 10.04 (Lucid Lynx)
Antworten |

BillMaier Team-Icon

Supporter

Anmeldungsdatum:
4. Dezember 2008

Beiträge: 6497

Irgendwie finde ich die find-Syntax sehr gewöhnungsbedürftig. Aber was schlimmer ist: Sie erscheint mir nicht immer logisch.

Dazu zwei Fragen:

* Wo genau muss denn jetzt die Aktion

-delete

stehen, damit sie ordentlich ausgeführt wird?

* Gibt es überhaupt eine grundsätzliche Regel für die richtige Reihenfolge aller Parameter?

In der manpage steht:

find [-H] [-L] [-P] [-D debugopts] [-Olevel] [path...] [expression]

Im Wiki finde ich das Beispiel:

find tmp -name "a" -exec touch {} \; -print

Ist nicht -name "a" das, was unter expressions zu verstehen ist?

Danke für Eure Hilfe.

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13217

BillMaier schrieb:

Irgendwie finde ich die find-Syntax sehr gewöhnungsbedürftig. Aber was schlimmer ist: Sie erscheint mir nicht immer logisch.

Warum?

* Wo genau muss denn jetzt die Aktion

-delete

stehen, damit sie ordentlich ausgeführt wird?

In der Manpage

       -delete
              Delete files; true if removal succeeded.  If the removal failed, an error message is issued.  If -delete
              fails, find's exit status will be nonzero (when it eventually  exits).   Use  of  -delete  automatically
              turns on the `-depth' option.

              Warnings:  Don't  forget  that  the  find command line is evaluated as an expression, so putting -delete
              first will make find try to delete everything below the starting points you specified.  When  testing  a
              find  command  line  that  you later intend to use with -delete, you should explicitly specify -depth in
              order to avoid later surprises.  Because -delete implies -depth, you  cannot  usefully  use  -prune  and
              -delete together.

* Gibt es überhaupt eine grundsätzliche Regel für die richtige Reihenfolge aller Parameter?

In der manpage steht:

find [-H] [-L] [-P] [-D debugopts] [-Olevel] [path...] [expression]

... aber auch:

       This  manual page documents the GNU version of find.  GNU find searches the directory tree rooted at each given
       file name by evaluating the given expression from left to right, according to the rules of precedence (see sec‐
       tion  OPERATORS),  until the outcome is known (the left hand side is false for and operations, true for or), at
       which point find moves on to the next file name.

und

       -Olevel
              Enables query optimisation.   The find program reorders tests to speed up execution while preserving the
              overall  effect;  that  is,  predicates with side effects are not reordered relative to each other.  The
              optimisations performed at each optimisation level are as follows.

              0      Equivalent to optimisation level 1.

              1      This is the default optimisation level and corresponds to the traditional behaviour.  Expressions
                     are  reordered  so that tests based only on the names of files (for example -name and -regex) are
                     performed first.

Im Wiki finde ich das Beispiel:

find tmp -name "a" -exec touch {} \; -print

Ist nicht -name "a" das, was unter expressions zu verstehen ist?

EXPRESSIONS
       The  expression  is made up of options (which affect overall operation rather than the processing of a specific
       file, and always return true), tests (which return a true or false value), and actions (which have side effects
       and return a true or false value), all separated by operators.  -and is assumed where the operator is omitted.

       If the expression contains no actions other than -prune, -print is performed on all files for which the expres‐
       sion is true.

Ciao

robert

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17625

Wohnort: Berlin

1
find tmp -name "a" -exec touch {} \; -print

tmp ist der path, in dem gesucht wird, und alles danach sind expressions, nicht nur -name "a".

Die Reihenfolge der Ausdrücke ist relevant - nicht immer, aber mit -delete fast immer.

1
find tmp -delete -name "a"

wird im Verzeichnis tmp alles löschen, und danach erst -name "a" ausführen - letzteres natürlich prächtig erfolglos, wenn zuvor alles gelöscht wurde.

1
find tmp -name a -delete

findet nur solche mit Namen a, und löscht diese. Wenn Du -name und -size benutzt:

1
find tmp -name a -size +10M -delete

dann spielt deren Reihenfolge keine Rolle:

1
find tmp -size +10M -name a -delete

Die großen Dateien mit Name a sind die gleichen wie die a-namigen, die groß sind. Die Filter sind kommutativ.

Wenn Du aber -ls dazwischenpackst:

1
find tmp -size -1k -ls -name "a*" -ls 

dann sieht die Ausgabe unterschiedlich aus (außer es gibt überhaupt nur die Dateien der Schnittmenge:

1
find tmp -name "a*" -ls  -size -1k -ls

* Wo genau muss denn jetzt die Aktion

-delete

stehen, damit sie ordentlich ausgeführt wird?

Egal wo sie steht - sie wird ordentlich ausgeführt ☺ . Fraglich ist nur, ob das das ist, was Du wünschst. In der Regel baut man filter, die von links nach rechts ausgewertet werden, und die alle zutreffen müssen, und rechts davon gibt man an, was mit den Dateien geschieht. Aber find läßt Dir die Freiheit verschiedene komplizierte Ausdrücke zusammenzubauen. Und gelegentlich ist man darüber auch glücklich.

BillMaier Team-Icon

Supporter
(Themenstarter)

Anmeldungsdatum:
4. Dezember 2008

Beiträge: 6497

Hirklm

Danke für copy-paste der richtigen Stellen. Das hilft.

rklm schrieb:

BillMaier schrieb:

Irgendwie finde ich die find-Syntax sehr gewöhnungsbedürftig. Aber was schlimmer ist: Sie erscheint mir nicht immer logisch.

Warum?

Vermutlich, weil ich zu wenig darüber weiß, wie find intern arbeitet.

* Wo genau muss denn jetzt die Aktion

-delete

stehen, damit sie ordentlich ausgeführt wird?

In der Manpage

       -delete
              Delete files; true if removal succeeded.  If the removal failed, an error message is issued.  If -delete
              fails, find's exit status will be nonzero (when it eventually  exits).   Use  of  -delete  automatically
              turns on the `-depth' option.

              Warnings:  Don't  forget  that  the  find command line is evaluated as an expression, so putting -delete
              first will make find try to delete everything below the starting points you specified.  When  testing  a
              find  command  line  that  you later intend to use with -delete, you should explicitly specify -depth in
              order to avoid later surprises.  Because -delete implies -depth, you  cannot  usefully  use  -prune  and
              -delete together.

Heißt das, ich kann -delete immer ganz ans Ende stellen und mach damit nichts falsch?

* Gibt es überhaupt eine grundsätzliche Regel für die richtige Reihenfolge aller Parameter?

In der manpage steht:

find [-H] [-L] [-P] [-D debugopts] [-Olevel] [path...] [expression]

... aber auch:

       This  manual page documents the GNU version of find.  GNU find searches the directory tree rooted at each given
       file name by evaluating the given expression from left to right, according to the rules of precedence (see sec‐
       tion  OPERATORS),  until the outcome is known (the left hand side is false for and operations, true for or), at
       which point find moves on to the next file name.

von links nach rechts, ok. Warum wird dann im Wiki das Beispiel

find \(-name "susi.*" -or -name "susanne.*" \) -name "*.txt"  

verwendet und nicht

find \ -name "*.txt"  (-name "susi.*" -or -name "susanne.*" \) 

?

Die erste Option (*.txt) dürfte doch schneller zu prüfen sein als eine -or - Verknüpfung. Oder geht man davon aus, dass es mehr *.txt-Dateien gibt, die alle weiter gereicht werden würden?

Danke und Gruß

BillMaier Team-Icon

Supporter
(Themenstarter)

Anmeldungsdatum:
4. Dezember 2008

Beiträge: 6497

Hallo user unknown auch Dir besten Dank.

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13217

BillMaier schrieb:

rklm schrieb:

BillMaier schrieb:

Irgendwie finde ich die find-Syntax sehr gewöhnungsbedürftig. Aber was schlimmer ist: Sie erscheint mir nicht immer logisch.

Warum?

Vermutlich, weil ich zu wenig darüber weiß, wie find intern arbeitet.

Was ich meinte: was erscheint Dir unlogisch?

Heißt das, ich kann -delete immer ganz ans Ende stellen und mach damit nichts falsch?

In den meisten Fällen wird das OK sein. Aber vielleicht willst Du ja auch so etwas machen:

1
find \( -type f -delete \) -o -print

von links nach rechts, ok. Warum wird dann im Wiki das Beispiel

find \(-name "susi.*" -or -name "susanne.*" \) -name "*.txt"  

verwendet und nicht

find \ -name "*.txt"  (-name "susi.*" -or -name "susanne.*" \) 

?

Die erste Option (*.txt) dürfte doch schneller zu prüfen sein als eine -or - Verknüpfung. Oder geht man davon aus, dass es mehr *.txt-Dateien gibt, die alle weiter gereicht werden würden?

Da musst Du vermutlich den Autor fragen. Aber wenn 90% der Dateien auf "susi.*" oder "susanne.*" matchen, dann kann es so rum schneller sein. In Wirklichkeit wird man es vermutlich nicht merken, da IO dominiert.

Du hast da übrigens ein Leerzeichen vergessen und den Backslash nicht mit verschoben. Und "-o" ist besser als "-or", weil das dem POSIX-Standard entspricht. Also lieber so:

1
2
find \( -name "susi.*" -o -name "susanne.*" \) -name "*.txt"
find -name "*.txt" \( -name "susi.*" -o -name "susanne.*" \)

Ciao

robert

BillMaier Team-Icon

Supporter
(Themenstarter)

Anmeldungsdatum:
4. Dezember 2008

Beiträge: 6497

Du hast da übrigens ein Leerzeichen vergessen

nicht ich, der Autor.

Da meld ich mich doch gleich im Wiki wieder.

Danke.

BillMaier Team-Icon

Supporter
(Themenstarter)

Anmeldungsdatum:
4. Dezember 2008

Beiträge: 6497

1
find \( -type f -delete \) -o -print

Heißt: lösche alle regulären Dateien und gib den Rest auf der Kommandozeile aus? Oder hab ich nicht verstanden, was das -o hier bedeutet?

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13217

BillMaier schrieb:

1
find \( -type f -delete \) -o -print

Heißt: lösche alle regulären Dateien und gib den Rest auf der Kommandozeile aus?

👍

BillMaier Team-Icon

Supporter
(Themenstarter)

Anmeldungsdatum:
4. Dezember 2008

Beiträge: 6497

BillMaier schrieb:

Irgendwie finde ich die find-Syntax sehr gewöhnungsbedürftig. Aber was schlimmer ist: Sie erscheint mir nicht immer logisch.

Gewöhnung +1

Logik +5

Ich danke Dir!

Antworten |