Como forçar apenas caminhos relativos na saída "localizar"?

25

Estou tentando criar um script que pode compactar arquivos com uma certa extensão em vários diretórios em um único tar-ball. Atualmente, o que tenho no arquivo de script é:

find "$rootDir" -name '*doc' -exec tar rvf docs.tar {} \;

Onde $rootDiré o caminho base para pesquisar.

Isso é bom, exceto que os caminhos são absolutos no arquivo tar. Eu preferiria que os caminhos fossem relativos $rootDir. Como eu faria isso?

Exemplo de corrente em tar -tf docs.tarque $rootDiré /home/username/testemitida:

home/username/test/subdir/test.doc
home/username/test/second.doc

O que eu desejo que a saída seja:

./subdir/test.doc
./second.doc
Shane
fonte

Respostas:

12

Se você executar a findpartir do diretório raiz desejado e não especificar um ponto de partida absoluto nas findopções de, ele exibirá caminhos relativos às tarinvocações de comando que constrói. Igual a:

cd $rootDir
find . -name '*doc' -exec tar rvf docs.tar {} \;

Se você não quiser alterar permanentemente o diretório de trabalho atual e estiver usando bashou semelhante ao seu shell, poderá fazê-lo

pushd $rootDir
find . -name '*doc' -exec tar rvf docs.tar {} \;
popd

em vez de.

Observe que pushd / popd não está presente em todos os shells, portanto verifique a página de manual, conforme apropriado. Eles estão presentes na implementação do bash, mas não na base sh, portanto, enquanto estiver usando explicitamente, /bin/bashvocê pode confiar neles, caso não seja solicitado por um script /bin/sh(pois isso pode ser mapeado para um shell menor que não possui aprimoramentos do bash)

David Spillett
fonte
Obrigado. Trabalhou brilhantemente. Não sabia que o linux tinha pushd / popd.
2111 Shane
3
Ou apenas use cd $rootDire cd - (pelo menos em bash). ( cd $rootDir ; find ... )também seria possível, ou seja, fazer tudo em um subshell.
Daniel Beck
9

Você pode usar o %Pformato na -printfdiretiva:

find ${rootDir} -name '*.doc' -printf "%P\n"

será exibido no seu exemplo:

subdir/test.doc
second.doc

Você pode usar esta findlista em uma forexpressão para executar nosso comando exec, como em:

for f in $( find ${rootDir} -name '*.doc' -printf "%P\n" );
do
    tar rvf docs.tar ${f}
done
Gabriel
fonte
1
A solução aceita funciona, mas é basicamente um hack. IMHO esta deve ser a solução certa para a pergunta.
Narcolessico 22/11
Obrigado Narcolessico. Também é MHO :-)
Gabriel