Bueno, por un lado, el -iinterruptor 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, -xy -L 1. La -L 1configura xargspara que llame a los comandos que desea que ejecuten los archivos de una sola manera.
Entonces esto anula el propósito de usar xargsaquí ya que si le das 1000 archivos, ejecutará el mvcomando 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 noxargssaber en este caso en el que en elmvcomando 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 usarxargsel 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
-itoma un argumento opcional. Como puso un espacio después-i, no hubo argumento para la-iopción y, por lo tanto, el siguiente-0no era una opciónxargssino 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 defindera 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 {}:-Ies similar a-i, pero toma un argumento obligatorio, por lo que el siguiente argumento pasado axargsse usa como argumento de la-Iopción. Luego, el argumento posterior es el-0que se interpreta como una opción, y así sucesivamente.Sin embargo, no deberías usarlo
-I {}en absoluto. Usar-Itiene tres efectos:-Idesactiva el procesamiento de cotizaciones, que-0ya lo hace.-Icambia la cadena para reemplazar, pero{}es el valor predeterminado.-Ihace 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
-Iy por-icompletoo 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