Usando o terminal Mac OS X para copiar uma seleção de pastas para um novo local, com o comportamento de mesclagem

2

Eu tenho uma pasta 'foo' que contém muitas subpastas, por exemplo

foo
 |---20101
 |---20102
 |---20103
 |---20111
 |---20112
 |---20113

Há muito mais do que isso, mas espero que isso explique o cenário. Agora eu quero copiar todas as pastas desta pasta que começam '2011' em um irmão de 'foo' chamado 'bar'. No entanto, 'bar' já contém algumas pastas com o mesmo nome

bar
 |---20111
 |---20113
 |---20114

O conteúdo da pasta de origem e destino deve ser mesclado. Observe que o script também precisará criar uma pasta bar / 20112, pois ela não existe.

Sou novo no script do Mac Terminal e tenho conseguido acertar as pastas certas

foo>ls | grep ^2011 

Que lista as pastas corretas, mas não tenho ideia de como passar isso para uma operação de cópia apropriada.

    
por ConfusedNoob 09.06.2013 / 19:30

1 resposta

7

O comando de cópia é cp . Se você der a ele o sinalizador -r (recursivo), ele fará exatamente o que você deseja, copiará arquivos em pastas existentes e criará novas pastas quando a pasta de destino estiver faltando.

No entanto, você nunca deve analisar a saída de ls , você deve usar find a href="http://tldp.org/LDP/abs/html/globbingref.html"> bash globbing :

cp -rv foo/2011* bar/

Se houver arquivos e pastas cujo nome comece com 2011 , use a opção find e seu -exec , que aplicará o comando fornecido a tudo que for encontrado por find (referido como {} ):

find foo/ -type d -name "2011*" -exec cp -rv '{}' bar/ \;

Neste caso específico, não há razão para salvar a saída de um comando e passá-lo para cp . Às vezes isso é necessário, então é assim que é feito. Em geral, a saída de um comando pode ser dada como entrada para outro comando se colocado dentro de comas invertidos ou $() .

cp -rv 'find foo/ -type d -name "2011*"' bar/

ou

cp -rv $(find foo/ -type d -name "2011*") bar/

Como alternativa, você pode percorrer os resultados:

for dir in $(find foo/ -type d -name "2011*"); do cp -rv "$dir" bar/; done

Isso fica mais complicado se os nomes dos arquivos / pastas puderem conter caracteres especiais ou novas linhas e coisas do gênero. Nesse caso, você deve fazer algo assim:

find foo/ -type d -name "2011*" | while IFS= read -r dir; do 
       cp -rv "$dir" bar/; 
done
    
por 09.06.2013 / 19:42