Mover um grande número de arquivos e diretórios para um diretório diferente

3

Eu estou tentando mover o seguinte movimento um grande número de arquivos que existem na seguinte estrutura para um / mnt / originals, mas eu preciso manter a estrutura ao mesmo tempo. Eu sei que o cp seria uma solução, mas não pode usar o cp por causa das limitações de espaço.

/mnt/originals-us/4
/mnt/originals.us/4/0b9
/mnt/originals.us/4/0b8
/mnt/originals.us/4/0b4
/mnt/originals.us/4/0b3
/mnt/originals.us/4/0b9/a62/
/mnt/originals.us/4/0b9/a47/
/mnt/originals.us/4/0b9/f0f/
/mnt/originals.us/4/0b9/a62/aa5/file16.png
/mnt/originals.us/4/0b9/a62/ba1/file1.png
/mnt/originals.us/4/0b9/a47/31f/file3.mov
/mnt/originals.us/4/0b9/f0f/
.
.
.

Etc. É um conjunto bastante grande de arquivos de diferentes nomes e tipos de arquivos. Eu tentei o seguinte, mas não funcionou.

mv /mnt/originals-us/ /mnt/originals/ 

mas obtenha o seguinte

mv: inter-device move failed: '/mnt/originals-us/10/0b9/' to '/mnt/originals/10/0b9'; unable to remove target: Is a directory

Eu também pensei em escrever um comando massivamente chanfrado, mas acho que isso não funcionaria também.

Isso é o que eu tenho até agora.

find . -type f -print | rev | cut -d '/' -f1 | rev

Isso obviamente me dá todos os nomes de arquivos, mas como faço para encadear com a primeira parte?

    
por Mark D 21.02.2014 / 17:28

2 respostas

6

Uma opção seria usar o rsync com --remove-source-files

rsync -vr --remove-source-files /mnt/originals-us/ /mnt/originals/

Possível advertência: não sei como o rsync verifica o espaço antes de executar ações potencialmente prejudiciais. Em um mundo perfeito, o rsync calculará quanto espaço é necessário, verificar se ele está disponível, abortar e avisar o usuário ou (se o espaço for adequado) executar a operação.

EDIT: Eu omiti a opção de recursão ( -r ) por engano, graças ao OP por mencionar, agora corrigido

    
por 21.02.2014 / 17:36
3

A solução rsync é muito mais eficiente, mas é possível com find também. O pior caso: um processo por arquivo:

find ... -exec cp --parents {} /dest/path \; -delete

find excluiria o arquivo de origem somente após a cópia bem-sucedida.

Mas podemos iniciar um projeto "divertido com descoberta" para otimização (remova echo s e \ antes de | após o teste):

find ... -type d -exec echo mkdir /target/{} \; -exec bash -c \
  'echo find {} -maxdepth 1 -type f -print0 \| '\
  'xargs -0 mv --target-directory=/target/{}' \;

No caso típico: 5 processos por diretório.

Com o seu exemplo (alguns arquivos por diretório), pode fazer sentido fazer um -print0 | xargs -0 mkdir na raiz de destino primeiro (e tirar a mkdir da chamada principal find ).

    
por 21.02.2014 / 18:09