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

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

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 explique o cenário. Agora quero copiar todas as pastas desta pasta que iniciam em '2011' para um irmão de 'foo' chamado 'bar'. Porém, 'bar' já contém algumas pastas com o mesmo nome

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

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

Sou novo em scripts de Terminal Mac e consegui acessar as pastas certas

foo>ls | grep ^2011 

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

Responder1

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

No entanto,você nunca deve analisar a saída dels, você deve usar findou, ainda mais simples,bash globbing:

cp -rv foo/2011* bar/

Se houver arquivos e pastas cujo nome comece com 2011, use finde sua -execopção que aplicará qualquer comando que você der a tudo 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á-la para cp. Isso às vezes é necessário, então veja como é feito. Em geral, a saída de um comando pode ser dada como entrada para outro comando se colocada entre aspas 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 de seus 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

informação relacionada