Tenho um diretório com a seguinte estrutura:
-- 201893208
└── 8Z12
└── ko_8Z12_Full
└── wp_we_8Z12_FullDAT
└── 8Z12_DATFull
└── P011
└── P011_Full
└── 8Z12_FullDAT
└── P011_DATFull
└── 9FZA
└── kl_wt-we-w_kl9-9FZA_Full
└── ffd-9FZA_FullDAT
└── 8fdZ12232_9FZA_DATFull
-- 903240920
└── P0fsa
└── P0fsa_Full
└── P0fsa_FullDAT
└── P0fsa_DATFull
└── Paaaf
└── we-Paaaf_ww_fl_Full
└── Paaaf_FullDAT
└── Paaaf_DATFull
└── 9FZATYYY
└── 9FZATYYY_Full
└── 9FZATYYY_FullDAT
-- wt0340291
└── OPF1121
└── OPF1121_Full
└── 8Z12_DATFull
└── KLOFJ9
└── lop_KLOFJ9_ffj_Full
└── powt_KLOFJ9_DATFull
└── LP02323
└── wr_we_LP02323_Full
└── wr_we_LP02323_FullDAT
Existem milhares de arquivos em cada pasta listada acima. E também há muitos subdiretórios dentro de cada um. Por exemplo 8Z12
, não contém apenas as três pastas listadas acima, mas também contém milhares de arquivos.
EU SÓ quero copiar diretórios que tenham _Full
no final de seu nome ( diretórios DATFull NÃO devem ser copiados ) E também contêm os padrões na lista abaixo
LP02323
KLOFJ9
Paaaf
9FZA
Em outras palavras, os diretórios que contêm uma string da lista acima E Full
em seu nome (mas NÃO DAT) devem ser copiados.
Portanto, no exemplo acima, apenas os seguintes diretórios (e todos os seus conteúdos e subdiretórios) devem ser copiados:
wr_we_LP02323_Full
lop_KLOFJ9_ffj_Full
we-Paaaf_ww_fl_Full
kl_wt-we-w_kl9-9FZA_Full
No meu entendimento, rsync
não suporta regex, portanto, isso deve ser feito find
antes de tudo (corrija-me se estiver errado). Mas como posso fazer isso de forma a garantir que todos os diretórios e subdiretórios sejam verificados e todas as pastas relevantes sejam copiadas mesmo que estejam enterradas muito profundamente em vários subdiretórios (observe que o exemplo acima foi um simplificado estrutura da minha pasta original).
Então ficam duas perguntas:
- Como posso fornecer a lista de padrões para
find
? - Como posso canalizar o resultado de
find
pararsync
?
Até agora, isso só me vem à mente para corresponder Full
:
find . -regextype sed -regex ".*/.*[^DAT]Full$"
Mas como posso adicionar a lista de IDs a este find
comando?
Usando um arquivo de strings que precisam estar presentes nos nomes dos diretórios, um shell loop sobre eles e
rsync
(supondo que queremos copiar do diretório na variável$source
e para o diretório na variável$target
):O que as opções
rsync
fazem (o primeiro acerto em qualquer um dos padrões de exclusão/inclusão é importante):--archive
: Copia a propriedade, permissões, carimbos de data/hora etc.--exclude='*DAT*/'
: Excluir qualquer diretório comDAT
em seu nome.--include='*/'
: Considere todos os diretórios (exceto os excluídos pelo padrão anterior). Isso é necessário pararsync
alcançar os diretórios reais nos quais você está interessado.--include="*$string*_Full/***"
: Considere todos os diretórios que correspondem ao padrão fornecido e tudo abaixo desse diretório. Se$string
forparrot
, isso seria--include="*parrot*_Full/***"
.--exclude='*'
: Não considere nada que ainda não esteja explicitamente incluído.--prune-empty-dirs
: Não transfira diretórios que não tenham nada explicitamente incluído neles.Se você quiser ver como
rsync
avalia os padrões ao executá-lo, adicione-vv
àrsync
linha de comando.Teste:
(executando o loop aqui)
Com uma única invocação de
rsync
:Uma
find
solução:Isso seria usado
find
para gerar uma lista dos subdiretórios que você gostaria de copiar. Estes são dados a um pequeno script embutido que faz um loop sobre eles.Em cada iteração do loop, o diretório correspondente no destino é criado (isso pressupõe uma cópia local) e o diretório é copiado usando
rsync
.Nunca use
find
para canalizar nomes de caminho para algum outro comando, a menos que você possa organizar para que os nomes de caminho sejam delimitados com segurança.Relacionado: