Bueno, por un lado, el -i
interruptor está en desuso:
-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.
Entonces, cuando cambié su comando a esto, funcionó:
$ find /foo/bar -name '*.mp4' -print0 | xargs -I{} -0 mv -t /some/path {}
Ejemplo
$ 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
...
Uso de -I{}
Este enfoque no debe usarse desde que se ejecuta esta construcción de comando:
$ find -print0 ... | xargs -I{} -0 ...
implícitamente activa estos interruptores a xargs
, -x
y -L 1
. La -L 1
configura xargs
para que llame a los comandos que desea que ejecuten los archivos de una sola manera.
Entonces esto anula el propósito de usar xargs
aquí ya que si le das 1000 archivos, ejecutará el mv
comando 1000 veces.
Entonces, ¿qué enfoque debo usar?
Puedes hacerlo usando xargs como este:
$ find /foot/bar/ -name '*.mp4' -print0 | xargs -0 mv -t /some/path
O simplemente haz que find lo haga todo:
$ find /foot/bar/ -name '*.mp4' -exec mv -t /some/path {} +
"This approach shouldn't be used"
qué enfoque debería usarse en su lugar? ¿"find /foot/bar/ -name '*.csv' -print0 | xargs -0 mv -t some_dir'"
Sería una mejor solución? Si es así, ¿cómo noxargs
saber en este caso en el que en elmv
comando para la alimentación de los argumentos que recibe de la tubería? (¿siempre los coloca al final?)find ... -exec ...
es una mejor manera o si quieres usarxargs
el tambiénfind ... | xargs ... mv -t ...
está bien. Sí, siempre los pone al final. Es por eso que ese método necesita el-t
.La opción
-i
toma un argumento opcional. Como puso un espacio después-i
, no hubo argumento para la-i
opción y, por lo tanto, el siguiente-0
no era una opciónxargs
sino el segundo de 6 operandos{} -0 mv -t /some/path {}
.Con solo la opción
-i
, xargs esperaba una lista de nombres de archivos separados por una nueva línea. Como probablemente no había una nueva línea en la entrada, xargs recibió lo que parecía un nombre de archivo enorme (con bytes nulos incrustados, pero xargs no lo comprobó). Esta cadena única que contiene la salida completa defind
era más larga que la longitud máxima de la línea de comando, de ahí el error "línea de comando demasiado larga".Su comando habría funcionado con en
-i{}
lugar de-i {}
. Alternativamente, podría haber usado-I {}
:-I
es similar a-i
, pero toma un argumento obligatorio, por lo que el siguiente argumento pasado axargs
se usa como argumento de la-I
opción. Luego, el argumento posterior es el-0
que se interpreta como una opción, y así sucesivamente.Sin embargo, no deberías usarlo
-I {}
en absoluto. Usar-I
tiene tres efectos:-I
desactiva el procesamiento de cotizaciones, que-0
ya lo hace.-I
cambia la cadena para reemplazar, pero{}
es el valor predeterminado.-I
hace que el comando se ejecute por separado para cada registro de entrada, lo cual es inútil aquí ya que su comando (mv -t
) está específicamente diseñado para hacer frente a múltiples archivos por invocación.O caer
-I
y por-i
completoo soltar xargs y usar
-exec
:fuente
Intenta usar un bash para el bucle:
o si desea ver lo que está pasando:
fuente
Si está viendo esto mientras usa la concha de pescado .
Esto se relaciona con la forma en que el pescado expande la cadena de reemplazo
{}
Si está utilizando pescado, debe escapar de la cadena de reemplazo
\{\}
o use una cadena de reemplazo diferente
fuente