Como fazer um tar compactado quando existem muitos nomes de arquivos para o shell expandir em uma única linha?

5

Normalmente eu faria algo como:

tar -czf archive.tar.gz *.csv

Mas quando há muitos arquivos no diretório para o shell expandir em uma única linha, isso não funciona.

Nestes casos, normalmente recorreria ao uso de find . Algo como:

find /path -name '*.csv' -exec tar -rf "./archive.tar.gz" {} +;'

Mas isso só parece funcionar se eu não incluir a opção -z , porque você não pode acrescentar arquivos compactados, e usar -c em vez de -r sobrescreverá o primeiro arquivo, já que vezes.

A única outra solução que posso criar é criar um arquivo .tar com find (como acima) e, em seguida, usar um segundo comando para compactá-lo. Existe uma maneira melhor de lidar com casos como esse?

Estou usando o Ubuntu Linux.

    
por Code Commander 07.09.2013 / 00:30

2 respostas

6

Como uma solução robusta, use find para separar nomes de arquivos por um caractere nulo e, em seguida, canalize diretamente para tar , que liga entrada delimitada por nulo :

find . -name '*.csv' -maxdepth 1 -print0 |
tar -czf archive.tgz --null -T -

Isso agora vai lidar com nomes de arquivos todos corretamente e também não é limitado pelo número de arquivos.

Usar ls para gerar uma lista de nomes de arquivos a serem analisados por outro programa é um antipadrão comum que deve ser evitado sempre que possível. find pode gerar saída delimitada por nulo ( -print0 ) que a maioria dos utilitários pode ler ou analisar mais. Como o caractere nulo é o único caractere que não pode aparecer em um nome de arquivo (e o / , obviamente), você sempre estará seguro com isso.

    
por 08.09.2013 / 13:23
8

Não, você não pode anexar a um arquivo tar compactado sem descompactá-lo primeiro.

No entanto, o tar pode aceitar sua lista de arquivos para processar de um arquivo , então você pode fazer:

ls *.csv > temp.txt
tar -zcf ball.tgz -T temp.txt

@slhck aponta que a solução acima não funcionará se houver espaços (e provavelmente outros caracteres irritantes) em seus nomes de arquivos. Esta versão inclui cada nome de arquivo entre aspas duplas:

ls *.csv | sed -e 's/^\(.*\)$/""/' > temp.txt
tar -zcf ball.tgz -T temp.txt

(Isto, naturalmente, quebrará se você tiver aspas duplas em seus nomes de arquivos, caso em que você recebe o que você merece.)

    
por 07.09.2013 / 00:38