Mover arquivos com find + xargs: o destino não é um diretório?

9

Quando eu executo o seguinte comando:

> mkdir some_dir
> find /foo/bar/ -name '*.csv' -print0 | xargs -0 mv {} some_dir

Eu recebo centenas de linhas que dizem:

mv: target '/foo/bar/XX.csv' is not a directory

Por quê? Eu pensei que xargs iria executar:

mv /foo/barXX.csv some_dir

para todos os arquivos que find encontrar. O que está acontecendo? By the way, isso é com zsh

Atualização:

Update1:

Eu tentei:

find /foo/bar/ -name '*.csv' -print0 | xargs -0 mv {} -t some_dir

mas depois tenho algumas linhas como:

mv: cannot stat '{}': No such file or directory

embora eu ache que o comando está movendo meus arquivos corretamente.

Update2:

Não pareço precisar da opção -t ao usar mv sozinho. Por exemplo

> touch file1.txt
> touch file2.txt
> mkdir my_dir
> mv  file1.txt  file2.txt  my_dir

funciona bem. Por que eu preciso de -t ao usar xargs ?

    
por Amelio Vazquez-Reina 20.07.2013 / 02:43

2 respostas

13

Supondo que você tenha o GNU ( find , xargs , & mv ), mude seu comando para isto:

$ find /foot/bar/ -name '*.csv' -print0 | xargs -0 mv -t some_dir

trecho da página de manualmv

   -t, --target-directory=DIRECTORY
          move all SOURCE arguments into DIRECTORY

O xargs ... acima irá construir o comando para que as chamadas a serem movidas sejam assim:

 $ mv 1.csv 2.csv 3.csv ... -t some_dir

Não precisa de xargs

Você pode ignorar essa abordagem fazendo com que find faça todo o trabalho:

$ find /foot/bar/ -name '*.csv' -exec mv -t some_dir {} +

Por que você precisa do mv -t ... ?

Isso tem a ver com a maneira como o xargs está construindo o conjunto de arquivos para passar para o comando que será executado a cada vez (ou seja, mv ... ).

Quando você executa o comando mv manualmente, controla quantos nomes de arquivo são passados para ele e, portanto, não precisa se preocupar em precisar do -t my_dir , pois sempre colocará o diretório de destino por último.

Referências

por 20.07.2013 / 03:01
1

Você também pode usar o comando ls em vez do comando find:

ls /foot/bar/*.csv | xargs  mv -t some_dir
    
por 04.03.2015 / 12:11

Tags