O GNU tar tem uma opção -T para obter a lista de arquivos de um arquivo especificado. Eu usaria find ... -print0 | tar cfzT outfile.tgz - --null então tar receber nomes de arquivos terminados com nulo em stdin .
Eu gostaria de criar um tarball que contenha arquivos de um diretório que tenha ctime de menos de 30 dias. A maioria dos tutoriais que eu encontrei basicamente recomendou fazer algo assim:
tar cvf foo.tar $(find ~/POD -type f -ctime -30)
O problema é que muitos dos arquivos que eu quero incluir contêm espaços em seus nomes. Isso significa que o comando tar delimitará com base em espaços, o que significa que os caminhos completos dos arquivos serão divididos.
Agora, estou tentando fazer com que o comando find retorne uma lista de caminhos de arquivos entre aspas. Então, aqui está o que eu tentei:
find . -type f -ctime -30 | xargs printf "\"%s\"\n"
Mas este comando também quebrou todos os nomes de arquivos baseados em espaços. Então tentei isso:
oldifs=$IFS
IFS=\n
find . -type f -ctime -30 | xargs printf "\"%s\"\n"
IFS=$oldifs
Mas isso me deu os mesmos resultados.
Existe uma maneira de passar os nomes dos caminhos completos para tar e ter tudo funcionando com espaços em seus nomes?
A saída com terminação nula é canalizada para tar sugerido pelo geekosaur deve fazer o truque, mas você também pode fazer isso com a opção -exec de find. Find sabe que este é um problema difícil, então eles resolveram isso, você só precisa reverter as coisas do que tentou fazer com tar … $(find …) e usar find para chamar tar assim:
find . -type f -ctime -30 -exec tar cfz outfile.tgz {} +
Você quase teve. Você precisa escapar \ n como $ '\ n' para atribuir uma nova linha a uma variável.
oifs=$IFS; IFS=$'\n'; tar cvf foo.tar $(find ~/POD -type f -ctime -30); IFS=$oifs
Veja a seção Quotes da página man do bash para mais informações.
Tags tar linux unix shell-scripting