O rsync não fala regex. Você pode inscrever o find e o grep, embora fique um pouco misterioso. Para encontrar os arquivos de destino:
find a/ |
grep -i 'name'
Mas todos eles são prefixados com "a /" - o que faz sentido, mas o que queremos é uma lista de padrões de inclusão aceitável para o rsync, e como o prefixo "a /" não funciona rsync eu vou removê-lo com o corte:
find . |
grep -i 'name' |
cut -d / -f 2-
Ainda há um problema - ainda vamos sentir falta de arquivos em subdiretórios, porque o rsync não pesquisa diretórios na lista de exclusão. Vou usar o awk para adicionar os subdiretórios de quaisquer arquivos correspondentes à lista de padrões de inclusão:
find a/ |
grep -i 'name' |
cut -d / -f 2- |
awk -F/ '{print; while(/\//) {sub("/[^/]*$", ""); print}}'
Tudo o que resta é enviar a lista para o rsync - podemos usar o argumento --include-from = - para fornecer uma lista de padrões para o rsync na entrada padrão. Então, ao todo:
find a/ |
grep -i 'name' |
cut -d / -f 2- |
awk -F/ '{print; while(/\//) {sub("/[^/]*$", ""); print}}' |
rsync -avvz --include-from=- --exclude='*' ./a/ ./b/
Observe que o diretório de origem 'a' é referido por dois caminhos diferentes - "a /" e "./a/". Isso é sutil, mas importante. Para tornar as coisas mais consistentes, farei uma alteração final e sempre me refiro ao diretório de origem como "./a/". No entanto, isso significa que o comando de corte deve ser alterado, pois haverá um "./" extra na frente dos resultados de find:
find ./a/ |
grep -i 'name' |
cut -d / -f 3- |
awk -F/ '{print; while(/\//) {sub("/[^/]*$", ""); print}}' |
rsync -avvz --include-from=- --exclude='*' ./a/ ./b/