Mit -exec … ;
kann die {}
Zeichenfolge beliebig oft im Befehl vorkommen, einschließlich null oder zwei oder mehr an einer beliebigen Position.
In diesem
Beispiel erfahren Sie, warum Sie möglicherweise auf die -exec
Verwendung von verzichten möchten {}
.
Mit zwei oder mehr Erscheinungen ist nützlich , vor allem , weil in (mindestens) einige Versionen von find
, der {}
brauchte kein Wort von mir zu sein; es kann andere Zeichen am Anfang oder am Ende haben; z.B,
find . -type f -exec mv {} {}.bak ";"
Mit -exec … +
der {}
Zeichenfolge muss erscheinen als letztes Argument vor dem +
. Ein Befehl wie
find . -name "*.bak" -exec mv {} backup_folder +
führt zu einer rätselhaften find: missing argument to ‘-exec’
Fehlermeldung.
Eine für die Befehle cp
und spezifische mv
Problemumgehung ist
find . -name "*.bak" -exec mv -t backup_folder {} +
oder
find . -name "*.bak" -exec mv --target-directory=backup_folder {} +
Das {}
muss ein Wort für sich sein; Es darf am Anfang oder am Ende keine anderen Zeichen enthalten. Und in (zumindest) einigen Versionen von find
haben Sie möglicherweise nicht mehr als eine {}
.
Ein vernünftiger Hinweis: Sie können sagen
finden . -name "* .sh" -type f -executable -exec {} optionale Argumente hier ";"
jedes Ihrer Skripte ausführen. Aber
finden . -name "* .sh" -Typ f -ausführbar -exec {} +
Führt eines Ihrer Skripte mit den Namen aller anderen als Parametern aus. Das ist ähnlich zu sagen
./*.sh
Als Shell-Befehl find
garantiert except nicht, dass die Ergebnisse sortiert werden. Sie können also nicht sicher sein, dass Sie aaa.sh
(Ihre alphabetisch erste *.sh
Datei) wie gewohnt ausführen ./*.sh
.
Ein Aspekt, der find
Anfängern möglicherweise nicht ganz klar ist, ist, dass die Befehlszeile effektiv eine ausführbare Anweisung in einer arkanen Sprache ist. Beispielsweise,
find . -name "*.sh" -type f -executable -print
meint
for each file
if the file’s name matches `*.sh` (i.e., if it ends with `.sh`)
then
if it is a plain file (i.e., not a directory)
then
if it is executable (i.e., the appropriate `---x--x--x` bit is set)
then
print the file’s name
end if
end if
end if
end loop
oder einfach,
for each file
if the file’s name matches `*.sh` AND it is a plain file AND it is executable
then
print the file’s name
end if
end loop
Einige der -
Schlüsselwörter sind sowohl eine ausführbare Aktion als auch ein Test. Dies gilt insbesondere für -exec … ;
; beispielsweise,
find . -type f -exec grep -q cat {} ";" -print
wird übersetzt in
für jede Datei
Wenn es sich um eine einfache Datei handelt (dh nicht um ein Verzeichnis)
dann
Führen Sie grep -q cat filename aus
wenn der Prozess erfolgreich ist (dh mit Status 0 beendet wird)
dann
Drucken Sie den Dateinamen
ende wenn
ende wenn
Schleife beenden
Dadurch werden die Namen aller Dateien gedruckt, die die Zeichenfolge " cat
" enthalten. Dies ist grep
zwar für sich allein möglich (mit der Option -l
(Kleinbuchstaben L
)), es kann jedoch nützlich sein, sie find
zum Suchen von Dateien zu verwenden, die eine bestimmte Zeichenfolge enthalten UND eine bestimmte Größe aufweisen UND einem bestimmten Eigentümer gehören UND wurden in einem bestimmten Zeitbereich geändert,….
Dies funktioniert jedoch nicht für -exec … +
. Da -exec … +
ein Befehl für mehrere Dateien ausgeführt wird, ist es nicht sinnvoll, ihn als logische Bedingung in einer for each file …
Schleife zu verwenden.
... -exec mv {} {}.bak ...
Beachten Sie, dass Ihr Beispiel nicht bei allenfind
Implementierungen erwartungsgemäß funktioniert . Die POSIX-Standardzustände{}
müssen einzeln angezeigt werden, um immer erkannt zu werden. Andernfalls kann das Verhalten die Zeichen unverändert lassen oder durch den Pfadnamen ersetzen. Im ersten Fall löscht Ihr gesamter Befehl im Wesentlichen alle Dateien außer den zuletzt gefundenen ...