Was ist das fehlende Argument für -exec?

15

Mit dem folgenden Befehl lösche ich ein Verzeichnis von Dateien und Verzeichnissen, die älter als 30 Tage sind, und verschiebe sie in ein Archivverzeichnis, das ich nach einigen Wochen löschen kann, wenn niemand nach ihren Dateien fragt. Das Zielverzeichnis hat Unterverzeichnisse nach Benutzernamen, ebenso das Archivverzeichnis.

Dies ist der Befehl, den ich benutze:

find /path/to/directory/username/ -mtime +30 -exec mv "{}" /path/to/archive/username/ \;

Ich schlug vor , eine leicht modifizierte Version dieses eine Frage zu beantworten auf fragen ubuntu, bearbeiten ein anderer Benutzer den Code , um das Ende der Zeile zu ändern , \;für +wie es ist schneller (und richtig?). Siehe hier

Die Verwendung +auf diese Weise funktioniert jedoch, wenn der -execBefehl ls -lhnicht in dem tatsächlichen Befehl enthalten ist, den ich verwende. Wenn ich es mit probiere +bekomme ich eine Fehlermeldung:

find: missing argument to '-exec'

Ich verstehe nicht, warum es sich so verhält oder was der richtige Befehl wäre. Bitte posten Sie nicht nur eine Befehlskorrektur, ich würde gerne verstehen, anstatt nur blind einem Vorschlag zu folgen.

Arronisch
quelle
Beziehen Sie sich auf diese Antwort ? Dies könnte erklären, warum
Wilf
Thanks @Wilf Ich habe aktualisiert, um zu zeigen, auf welche Antwort die Bearbeitung stattgefunden hat. Der von Ihnen angegebene Link enthält einen weiteren Link, der erklärt, wie mein Gehirn damit umgehen kann.
Arronical
Dank an @souravc in einer brillant zyklischen Art und Weise ist diese Frage von dem Benutzer, der meinen Befehl bearbeitet hat! Endlich bekomme ich, dass es +mehrere Argumente für den gleichen Befehl liefert, aber ich komme damit nicht klar mv!
Arronical
@Arronical mv kann, siehe meine Antwort ^^
Chaos

Antworten:

19

Der Benutzer in diesem Beitrag kann sagen, dass das +Zeichen am Ende eines -execBefehls schneller ist, aber nicht warum.

Nehmen wir an, der findBefehl gibt die folgenden Dateien zurück:

/path/to/file1
/path/to/file2
/path/to/file3

Der normale -execBefehl ( -exec command {} \;) wird für jede übereinstimmende Datei einmal ausgeführt. Beispielsweise:

find ... -exec mv {} /target/ \;

Führt aus:

mv /path/to/file1 /target/
mv /path/to/file2 /target/
mv /path/to/file3 /target/

Wenn Sie +sign ( -exec command {} +) verwenden, wird der Befehl erstellt, indem am Ende des Befehls mehrere übereinstimmende Dateien hinzugefügt werden. Beispielsweise:

find ... -exec mv -t /target/ {} +

Führt aus:

mv -t /target/ /path/to/file1 /path/to/file2 /path/to/file3

Um das +Flag korrekt zu verwenden, muss sich das zu verarbeitende Argument am Ende des Befehls und nicht in der Mitte befinden. Das ist der Grund, warum findTrows missing argument to '-exec'in Ihrem Beispiel sind. es verfehlt den Abschluss {}.

Chaos
quelle
Ich habe mich immer gefragt, warum es find -execerforderlich ist {}, das letzte Argument zu sein, wenn es mit verwendet wird +. Weiß jemand, warum diese Entwurfsentscheidung getroffen wurde, anstatt Konstrukte wie die Befehlszeile des OP funktionieren zu lassen?
Peter Cordes
11

Der User erklärte ihre Bearbeitung ....

Der Terminator von '+' exec ist schneller als '\;'  siehe /ubuntu/558817/was-ist-der- Unterschied- zwischen-benutzung-und-ausführung-;  und das Erstellen einer Sicherungsdatei aus der Originaldatei ist eine gute Idee

... über diesen Link . Ich denke, anstatt mehrere Befehle zu verwenden, werden alle Dateinamen an eine Befehlsinstanz gesendet, um die Dinge zu beschleunigen. Hier ist ein Beispiel von hier :

Wird -exec mit einem Semikolon ( find . -exec ls '{}' \;) verwendet, wird ausgeführt

ls file1
ls file2
ls file3

Wenn Sie stattdessen ein Pluszeichen ( find . -exec ls '{}' \+) verwenden, werden alle Dateinamen als Argumente an einen einzelnen Befehl übergeben:

ls file1 file2 file3

Es gibt auch andere Formulare mit ;und +(von hier aus :)

Daher ist die folgende Beispielsyntax für den Befehl find zulässig:

find . -exec echo {} \;
find . -exec echo {} ';'
find . -exec echo {} ";"
find . -exec echo {} \+
find . -exec echo {} +

Ich bin mir jedoch nicht sicher, ob dies mit dem Befehl move funktioniert, da es sich um eine Syntax handelt mv [OPTION]... SOURCE DEST, sofern nicht die -tOption oder eine ähnliche Option verwendet wird. Es sollte jedoch lsohne zusätzliche Optionen usw. funktionieren, da sie verstehen können, wenn mehrere Dateinamen angegeben werden. Die müssen +möglicherweise auch entkommen (dh \+)

Wilf
quelle
Beide tollen Antworten, aber ich muss es dem Chaos zumuten, weil ich ein bisschen schneller bin und die mv -tbeiden +1 erkläre !
Arronical