Nun, zum einen ist der -i
Schalter veraltet:
-i[replace-str]
This option is a synonym for -Ireplace-str if replace-str is specified.
If the replace-str argument is missing, the effect is the same as -I{}.
This option is deprecated; use -I instead.
Als ich Ihren Befehl in diesen änderte, funktionierte es:
$ find /foo/bar -name '*.mp4' -print0 | xargs -I{} -0 mv -t /some/path {}
Beispiel
$ find . -print0 | xargs -I{} -0 echo {}
.
./.sshmenu
./The GIT version control system.html
./.vim_SO
./.vim_SO/README.txt
./.vim_SO/.git
./.vim_SO/.git/objects
./.vim_SO/.git/objects/pack
./.vim_SO/.git/objects/pack/pack-42dbf7fe4a9b431a51da817ebf58cf69f5b7117b.idx
./.vim_SO/.git/objects/pack/pack-42dbf7fe4a9b431a51da817ebf58cf69f5b7117b.pack
./.vim_SO/.git/objects/info
./.vim_SO/.git/refs
./.vim_SO/.git/refs/tags
...
Gebrauch von -I{}
Dieser Ansatz sollte nicht verwendet werden, da dieses Befehlskonstrukt ausgeführt wird:
$ find -print0 ... | xargs -I{} -0 ...
implizit schaltet dieser Schalter auf xargs
, -x
und -L 1
. Das -L 1
konfiguriert xargs
so, dass es die Befehle aufruft, über die die Dateien auf eine einzige Weise ausgeführt werden sollen.
Dies macht den Zweck der Verwendung dieses Befehls xargs
zunichte, da der mv
Befehl 1000-mal ausgeführt wird, wenn Sie 1000 Dateien angeben .
Welchen Ansatz soll ich dann verwenden?
Du kannst es mit xargs wie folgt machen:
$ find /foot/bar/ -name '*.mp4' -print0 | xargs -0 mv -t /some/path
Oder einfach alles finden lassen:
$ find /foot/bar/ -name '*.mp4' -exec mv -t /some/path {} +
"This approach shouldn't be used"
welcher Ansatz sollte stattdessen verwendet werden? Wäre"find /foot/bar/ -name '*.csv' -print0 | xargs -0 mv -t some_dir'"
eine bessere Lösung? Wenn ja, wie istxargs
in diesem Fall wissen , wo in dermv
Befehl - Feed in den Argumenten aus dem Rohr kommt? (Platziert es sie immer zuletzt?)find ... -exec ...
ein besserer Weg, oder wenn Sie verwenden mögen ,xargs
dasfind ... | xargs ... mv -t ...
ist auch in Ordnung. Ja, es bringt sie immer an die letzte Stelle. Deshalb braucht diese Methode die-t
.Die Option
-i
akzeptiert ein optionales Argument. Da Sie nach ein Leerzeichen setzen-i
, gab es kein Argument für die-i
Option und daher war das folgende-0
keine Option fürxargs
den zweiten von 6 Operanden{} -0 mv -t /some/path {}
.Mit nur der Option
-i
erwartete xargs eine durch Zeilenumbrüche getrennte Liste von Dateinamen. Da die Eingabe wahrscheinlich keine neue Zeile enthielt, erhielt xargs einen riesigen Dateinamen (mit eingebetteten Null-Bytes, aber xargs überprüfte das nicht). Diese einzelne Zeichenfolge, die die gesamte Ausgabe von enthält,find
war länger als die maximale Befehlszeilenlänge, daher der Fehler "Befehlszeile zu lang".Ihr Befehl hätte
-i{}
statt mit gearbeitet-i {}
. Alternativ hätten Sie auch Folgendes verwenden können-I {}
:-I
ist ähnlich-i
, verwendet jedoch ein obligatorisches Argument, sodass das nächste Argument, das an übergebenxargs
wird, als Argument der-I
Option verwendet wird. Dann wird das folgende Argument-0
als Option interpretiert und so weiter.Sie sollten jedoch überhaupt nicht verwenden
-I {}
. Verwenden-I
hat drei Effekte:-I
deaktiviert die Angebotsverarbeitung, die dies-0
bereits tut.-I
Ändert die zu ersetzende Zeichenfolge, ist jedoch{}
der Standardwert.-I
Bewirkt, dass der Befehl für jeden Eingabedatensatz separat ausgeführt wird. Dies ist hier unbrauchbar, da Ihr Befehl (mv -t
) speziell dafür vorgesehen ist, mit mehreren Dateien pro Aufruf umzugehen.Entweder fallen lassen
-I
und-i
ganzoder lösche xargs und benutze
-exec
:quelle
Versuchen Sie es mit einer Bash for-Schleife:
oder wenn Sie sehen möchten, was los ist:
quelle
Wenn Sie dies sehen, während Sie die Fischschale verwenden .
Dies bezieht sich darauf, wie Fische die Ersatzschnur ausdehnen
{}
Wenn Sie Fisch verwenden, müssen Sie die Ersatzschnur entkommen
\{\}
oder verwenden Sie eine andere Ersatzzeichenfolge
quelle