Como copiar arquivos no shell unix usando curingas

6

Estou tentando copiar alguns arquivos em pastas existentes. Este é um exemplo do esquema

# origin 
/home/user/myfiles/folder1/group1/1.jpg
/home/user/myfiles/folder1/group1/2.jpg
/home/user/myfiles/folder1/group2/1.jpg
/home/user/myfiles/folder1/group2/2.jpg
/home/user/myfiles/folder2/group1/1.jpg
/home/user/myfiles/folder2/group1/2.jpg
/home/user/myfiles/folder2/group2/1.jpg
/home/user/myfiles/folder2/group2/2.jpg

O esquema da pasta de destino já existe, são apenas os arquivos de origem (jpgs) que não estão lá.

Minha pergunta é como fazer isso?

Eu gostaria de terminar com algo como abaixo, mas isso não está funcionando. Talvez eu deva incluir regex na consulta para separar o asterisco em valores e usar como origem / destino?

 cp /home/user/myfiles/*/*/*.jpg  /home2/user/myfiles/*/*/*.jpg

Minha intenção original é usar este esquema de cópia na minha pergunta não respondida: s3cmd: como copiar arquivos do local para o bucket S3 com a estrutura existente como uma possível solução.

    
por Martin 26.07.2012 / 01:26

2 respostas

3

Com o GNU cp você pode usar a opção --parents , assim:

cd /home/user/myfiles ; cp --parents */*/*.jpg /home2/user/myfiles/

Você precisa cd primeiro, porque se você usar cp --parents /home/user/myfiles/... , ele criará esses pais também e você terá /home2/user/myfiles/home/parents/myfiles/ .

Se você precisar de uma resposta não-GNUish, o método tradicional unix seria tar sobre um pipe.

cd /home/user/myfiles ; tar cf - */*/*.jpg | ( cd /home2/user/myfiles ; tar xf - )

O segundo cd está em um subshell com o segundo tar, então é onde os arquivos são extraídos. O tarball em si é criado, enviado pelo pipe e extraído tudo ao mesmo tempo. Adicione um sinalizador v a um dos tars se quiser um relatório de andamento.

    
por 26.07.2012 / 09:35
1

O seguinte deve fazer o truque:

for i in 'find /home/user/myfiles/folder1 -print'; do 
  if [ ! -d $i ]; 
    then filePath='echo $i | cut -f 4- -d"/"'; 
         cp $i /home/user/myfiles/folder2/$filePath; 
  fi; 
done

Basicamente, estou extraindo a parte do nome do arquivo que vai mudar entre as duas pastas e, em seguida, emitindo um comando de cópia.

Observe o "cut -f 4 - " acima - ele recebe os campos do 4º em diante. Você pode mudar o número conforme seu desejo

Talvez até basename ou um comando mais simples exista ... mas isso será feito por enquanto:)

    
por 26.07.2012 / 03:49

Tags