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 -r
sinalizador (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 find
ou, ainda mais simples,bash globbing:
cp -rv foo/2011* bar/
Se houver arquivos e pastas cujo nome comece com 2011
, use find
e sua -exec
opçã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