Bem, por um lado, o -i
switch foi descontinuado:
-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.
Então, quando eu mudei seu comando para isso, funcionou:
$ find /foo/bar -name '*.mp4' -print0 | xargs -I{} -0 mv -t /some/path {}
Exemplo
$ 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{}
Essa abordagem não deve ser usada desde a execução deste comando:
$ find -print0 ... | xargs -I{} -0 ...
Acontece implicitamente nesses muda para xargs
, -x
e -L 1
. Ele é -L 1
configurado xargs
para chamar os comandos pelos quais você deseja executar os arquivos de uma única maneira.
Portanto, isso anula o propósito de usar xargs
aqui, pois se você fornecer 1000 arquivos, ele executará o mv
comando 1000 vezes.
Então, qual abordagem devo usar então?
Você pode fazer isso usando xargs assim:
$ find /foot/bar/ -name '*.mp4' -print0 | xargs -0 mv -t /some/path
Ou apenas encontre fazer tudo:
$ find /foot/bar/ -name '*.mp4' -exec mv -t /some/path {} +
"This approach shouldn't be used"
que abordagem deveria ser usada, então? Seria"find /foot/bar/ -name '*.csv' -print0 | xargs -0 mv -t some_dir'"
uma solução melhor? Se sim, como éxargs
que, nesse caso, onde está omv
comando para alimentar os argumentos que obtém do pipe? (sempre os coloca por último?) #find ... -exec ...
uma maneira melhor ou se você quiser usarxargs
ofind ... | xargs ... mv -t ...
é muito fina. Sim, sempre os coloca por último. É por isso que esse método precisa do-t
.A opção
-i
aceita um argumento opcional. Como você colocou um espaço depois-i
, não houve argumento para a-i
opção e, portanto, o subsequente-0
não era uma opção,xargs
mas o segundo dos 6 operandos{} -0 mv -t /some/path {}
.Com apenas a opção
-i
, xargs esperava uma lista separada por nova linha de nomes de arquivos. Como provavelmente não havia nova linha na entrada, o xargs recebeu o que parecia ser um nome de arquivo enorme (com bytes nulos incorporados, mas o xargs não verificou isso). Essa sequência única contendo toda a saída defind
era maior que o comprimento máximo da linha de comando, daí o erro “linha de comando muito longa”.Seu comando teria trabalhado com em
-i{}
vez de-i {}
. Como alternativa, você poderia ter usado-I {}
:-I
é semelhante a-i
, mas aceita um argumento obrigatório, portanto o próximo argumento passado para oxargs
é usado como o argumento da-I
opção. Em seguida, o argumento a seguir é o-0
que é interpretado como uma opção e assim por diante.No entanto, você não deve usar
-I {}
nada. O uso-I
tem três efeitos:-I
desativa o processamento de cotação, o que-0
já faz.-I
altera a cadeia para substituir, mas{}
é o valor padrão.-I
faz com que o comando seja executado separadamente para cada registro de entrada, o que é inútil aqui, pois seu comando (mv -t
) se destina especificamente a lidar com vários arquivos por chamada.Deixar cair
-I
e-i
completamenteou solte xargs e use
-exec
:fonte
Tente usar um loop bash para:
ou se você quiser ver o que está acontecendo:
fonte
Se você estiver vendo isso enquanto estiver usando a casca do peixe .
Isso se refere a como o peixe expande a cadeia de substituição
{}
Se você estiver usando peixe, precisará escapar da corda de substituição
\{\}
ou use uma sequência de substituição diferente
fonte