Usando find e tar com arquivos com caracteres especiais no nome

5

Eu quero arquivar todos os arquivos .ctl em uma pasta, de forma recursiva.

tar -cf ctlfiles.tar 'find /home/db -name "*.ctl" -print'

A mensagem de erro:

tar: Removing leading '/' from member names
tar: /home/db/dunn/j: Cannot stat: No such file or directory
tar: 74.ctl: Cannot stat: No such file or directory

Eu tenho estes arquivos: / home / db / dunn / j 74.ctl e j 75. Observe o espaço extra. E se os arquivos tiverem outros caracteres especiais? Como faço para arquivar esses arquivos recursivamente?

    
por Costi 02.06.2010 / 01:07

3 respostas

5

Use o recurso -T do tar para dizer a ele para ler a lista de arquivos de outro arquivo (o tar trata cada linha como um arquivo separado).

Em seguida, você pode usar a notação <() para que seu shell gere um pseudo-arquivo a partir da saída de um comando:

tar cf ctlfiles.tar -T <(find /home/db -name "*.ctl")

Se o seu shell não suporta a notação <() , você pode usar um arquivo temporário:

find /home/db -name "*.ctl" > ctlfile-list
tar cf ctlfiles.tar -T ctlfile-list
rm ctlfile-list
    
por 02.06.2010 / 01:24
4

Você pode usar o recurso -print0 do find com o recurso -0 do xargs, assim:

find /home/db -name '*.ctl' -print0 | xargs -0 tar -cf ctlfiles.tar

-print0 (hífen-impressão-zero) diz ao find para usar um nulo como o delimitador entre caminhos em vez de espaços, e -0 (esse hífen zero) diz ao xargs para esperar o mesmo.

Editado para adicionar:

Se você tiver um grande número de arquivos, o xargs pode invocar o tar mais de uma vez. Veja comentários sobre maneiras de lidar com isso, ou faça invocar o tar diretamente, como este, que funciona com qualquer número de arquivos, mesmo se eles tiverem espaços ou novas linhas em seus nomes:

rm -f ctlfiles.tar
find /home/db -name '*.ctl' -exec tar -rf ctlfiles.tar {} \;

Mas provavelmente é menos eficiente, pois invocará o tar (no modo append) uma vez para cada arquivo.

    
por 02.06.2010 / 01:14
1

Quando o argumento após "-T" é "-", a lista de arquivos é retirada de stdin. Versões recentes do tar normalmente suportam a opção "-null", que indica que os arquivos dados na fonte especificada pela opção "-T" são separados por nulo.

Por isso, o seguinte funciona com um número arbitrário de arquivos, possivelmente contendo caracteres de nova linha:

find /home/db -name '*.ctl' -print0 | tar --null -T - -cf ctlfiles.tar
    
por 26.04.2012 / 15:29