
Eu tenho a seguinte estrutura de diretórios:
test/
test/1/
test/foo2bar/
test/3/
Quero compactar o diretório "test" excluindo tudo o que está nos subdiretórios (profundidade não predefinida), que inclui as strings "1" ou "2" neles. No bash shell, eu quero usarencontrare alimentar sua saída paraalcatrão. eu primeiro testoencontrar:
find test/ -not -path "*1*" -not -path "*2*"
Saída:
test/
test/3
Ótimo. Então eu combino comalcatrão:
find test/ -not -path "*1*" -not -path "*2*" | tar -czvf test.tar.gz --files-from -
Saída:
test/
test/3/
test/1/
test/foo2bar/
test/3/
Na verdade, tanto "test/1" quanto "test/foo2bar" estão presentes no arquivo.Por que esses argumentos foram passados para o tar, se eles não deveriam estar presentes na saída do find?
Responder1
Para expandir o que @cuonglm disse, tar
por padrão opera recursivamente. Se você passar um nome de diretório, ele arquivará oconteúdodesse diretório.
Você pode modificar seu find
comando para retornar apenas os nomes dos arquivos, não dos diretórios...
find test/ -type f -not -path "*1*" -not -path "*2*" |
tar -czvf test.tar.gz --files-from -
Em vez disso, você poderia usar o --no-recursion
sinalizador para tar
:
find test/ -not -path "*1*" -not -path "*2*" |
tar -czvf test.tar.gz --no-recursion --files-from -
O que resulta em:
test/
test/3/
A --no-recursion
bandeira é específica para GNU tar. Se você estiver usando outra coisa, consulte a página de manual apropriada para ver se há um recurso semelhante disponível.
Observe que seu find
comando excluiráarquivosque contêm 1
ou 2
no caminho, bem como diretórios.
Responder2
Com o GNU tar, você também pode usar a --exclude
opção de excluir arquivos com base em nomes.
$ tar --exclude "*1*" --exclude "*2*" -cvf foo.tar test/
test/
test/3/
Há também -X
or --exclude-from
which pega um arquivo para ler os padrões de exclusão.
Embora as find -not -path "*1*"
, isso também excluirá arquivos cujos nomes contenham um 1
ou 2
. Para apenas pulardiretórioscujos nomes correspondem ao padrão, use find -prune
e tar --no-recursion
:
$ touch test/3/blah.1
$ find test/ -type d \( -name "*1*" -o -name "*2*" \) -prune -o -print |
tar cvf test.tar --files-from - --no-recursion
test/
test/3/
test/3/blah.1
(Pelo menos GNU tar e FreeBSD tar possuem --no-recursion
)