it-swarm.com.de

`find` mit mehreren` -name` und` -exec` führt nur die letzten Übereinstimmungen von `-name` aus

Wenn ich benutze

find . -type f -name "*.htm*" -o -name "*.js*" -o -name "*.txt"

es werden alle Dateitypen gefunden. Aber wenn ich am Ende -exec Füge:

find . -type f -name "*.htm*" -o -name "*.js*" -o -name "*.txt" -exec sh -c 'echo "$0"' {} \;

es scheint, dass nur .txt - Dateien gedruckt werden. Was mache ich falsch?

Hinweis: Verwenden von MINGW (Git Bash)

77
jakub.g
finden . -type f -name "* .htm *" -o -name "* .js *" -o -name "* .txt"

kurzform für:

finden . \ (\ (() -Typ f -ein -name "* .htm *" \)  \ 
\( -name "* .js *" \)  \ 
\( -name "* .txt" \) \
       \) -Ein Druck

Das heißt, weil kein Aktion Prädikat angegeben ist (nur Bedingungen), ein -print Aktion wird implizit für die Dateien hinzugefügt, die den Bedingungen entsprechen.

(und das würde übrigens nicht reguläres .js Dateien (die -type f gilt nur für .htm Dateien)).

Während:

finden . -type f -name "* .htm *" -o -name "* .js *" -o -name "* .txt"\
 -exec sh -c 'echo "$ 0"' {}\; 

kurzform für:

finden . \ ( -Typ f -ein -name "* .htm *" \)  \ 
\( -name "* .js *" \)  \ 
\( -name "* .txt" -ein -exec sh -c 'echo "$ 0"' {} \; \)

Für find (wie in vielen Sprachen) UND (-a; implizit, wenn weggelassen) hat Vorrang vor ODER (-o) und Hinzufügen eines expliziten Aktionsprädikats (hier -exec) bricht das -print implizite Aktion wie oben gezeigt. Hier möchten Sie:

find . -type f \( -name "*.htm*" -o -name "*.js*" -o -name "*.txt" \) \
  -exec sh -c 'echo "$0"' {} \;

Oder:

find . -type f \( -name "*.htm*" -o -name "*.js*" -o -name "*.txt" \) -exec sh -c '
   for i do
     echo "$i"
   done' sh {} +

Um zu vermeiden, dass ein sh pro Datei ausgeführt wird.

105

Es sind die impliziten Klammern. Fügen Sie explizite Klammern hinzu. \(\)

find . -type f \( -name "*.htm*" -o -name "*.js*" -o -name "*.txt" \) -exec sh -c 'echo "$0"' {} \;

oder mit xargs (ich mag xargs, ich finde es einfacher, aber anscheinend nicht so portabel).

find . -type f \( -name "*.htm*" -o -name "*.js*" -o -name "*.txt" \) -print0 | xargs -0 -n1 echo
29
ctrl-alt-delor