Estou tentando executar o rsync para copiar alguns arquivos recursivamente por um caminho com base em seu padrão de nome de arquivo, sem distinção entre maiúsculas e minúsculas . Isto é o que eu fiz para executar o rsync:
$ rsync -avvz --include ='*/' --include='.*[Nn][Aa][Mm][E].*' --exclude='*' ./a/ ./b/
Nada é copiado, a saída de depuração mostra:
[sender] hiding file 1Name.txt because of pattern *
[sender] hiding file 1.txt because of pattern *
[sender] hiding file 2.txt because of pattern *
[sender] hiding file Name1.txt because of pattern *
[sender] hiding directory test1 because of pattern *
[sender] hiding file NaMe.txt because of pattern *
Eu tentei usar: --include='*[Nn][Aa][Mm][E]*'
e outras combinações, mas ainda não vai.
Alguma idéia de como usar o regex para incluir alguns arquivos?
--exclude='*'
?Respostas:
O rsync não fala regex. Você pode recrutar find e grep, apesar de ficar um pouco misterioso. Para encontrar os arquivos de destino:
Mas todos são prefixados com "a /" - o que faz sentido, mas o que queremos terminar é uma lista de padrões de inclusão aceitáveis para rsync e como o prefixo "a /" não funciona para rsync I ' vou removê-lo com corte:
Ainda existe um problema - ainda vamos perder os arquivos nos subdiretórios, porque o rsync não pesquisa diretórios na lista de exclusões. Vou usar o awk para adicionar os subdiretórios de qualquer arquivo correspondente à lista de padrões de inclusão:
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, no total:
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 precisa ser alterado, pois haverá um "./" extra na frente dos resultados de find:
fonte
-t
é um switch válido.sed "s#^$1/*##"
buuuut que quebrará em caminhos que contenham um #. Para consertar isso, precisamos citar o nome do diretório recebido:prefix=$(echo "$1" | sed 's#/#\\/#g')
e entãosed "s/^$prefix\\/*//"
os sutilezas da citação do bash são um pouco de pesadelo;)Eu sugeriria usar a opção de filtro do rsync. Para o seu exemplo, digite:
a primeira regra de filtro informa ao rsync quais padrões incluir. A segunda regra é necessária para solicitar ao rsync que inspecione todos os diretórios em sua travessia. Para impedir a inclusão de diretórios vazios, eles são excluídos explicitamente por
-m
opção. A última regra de filtro diz ao rsync para descartar todos os padrões restantes que ainda não correspondiam até o momento.fonte
Se você usar o ZSH, poderá usar o sinalizador (#i) para desativar a distinção entre maiúsculas e minúsculas. Exemplo:
O ZSH também suporta exclusões, que são especificadas como o caminho regular, mas têm uma inicial ~
Você pode encadear exclusões:
Finalmente, você pode especificar que tipo de arquivo você deseja retornar (diretório, arquivo, etc). Isso é feito com (/) para o diretório e (.) Para o arquivo.
Com base em tudo isso, eu faria esse comando como:
(Não vejo necessidade de exclusão com esses seletores)
fonte
A resposta do @ sqweek acima é impressionante, embora eu suspeite que ele tenha um bug em seu
awk
script para gerar diretórios principais, pois isso me dá, por exemplo:Consegui corrigi-lo usando
gensub
:Portanto, sua solução completa, com o
awk
bit alterado, seria:fonte
sub("/[^/]*$")
).Tentei com um script c #, pois é a linguagem que eu tenho mais experiência. Eu sou capaz de criar a lista de arquivos que eu quero incluir, mas alguém rsync ainda está me dizendo para fazer uma caminhada. Ele cria as pastas, mas ignora os arquivos. Aqui está o que eu tenho ..
Primeiro o conteúdo do diretório:
Em seguida, a saída do script C #:
E a saída de depuração:
fonte
[EDIT] Isso funciona apenas localmente. Para caminhos remotos, a estrutura de diretórios deve ser criada primeiro.
Mais simples que a resposta aceita; Use --file-from, que inclui diretórios pai automaticamente e imprima o caminho do arquivo com% P
Então você só precisa usar
find
ersync
.fonte