Você sempre pode fazer:
ls *.tgz | grep -v Broad_hapmap3_r2_Affy6_cels_excluded.tgz | xargs -n1 tar zxvf
Mas eu suspeito que alguém vai postar uma maneira mais limpa fazer isso diretamente do shell bash sem precisar de um grep lá.
Eu tenho um diretório que parece
$ ls
Broad_hapmap3_r2_Affy6_cels_excluded.tgz DINGO.tgz GIGAS.tgz index.html IONIC.tgz passing_cels_sample_map.txt SCALE.tgz
CHEAP.tgz EPODE.tgz HOMOS.tgz index.html?C=M;O=A LOVED.tgz PICUL.tgz SHELF.tgz
CORER.tgz excluded_cels_md5.txt HUFFS.tgz index.html?C=N;O=D NIGHS.tgz POSIT.tgz SLOTH.tgz
CUPID.tgz excluded_cels_sample_map.txt HUSKS.tgz index.html?C=S;O=A passing_cels_md5.txt SAKES.tgz TESLA.tgz
Eu quero descompactar todos os arquivos que correspondem à extensão * .tgz com um único comando, exceto Broad_hapmap3_r2_Affy6_cels_excluded.tgz.
Eu posso fazer
ls *.tgz | xargs -n1 tar zxvf
para todos os arquivos * tgz, mas qual é uma boa maneira de excluir um subconjunto deles? De ler on-line talvez encontrar é indicado nesta situação, mas parece um exagero. Agradeço antecipadamente.
Adendo: também estaria interessado em métodos alternativos para a pergunta sem excluir arquivos.
No zsh:
setopt extended_glob
for z in *.tgz~Broad_hapmap3_r2_Affy6_cels_excluded.tgz; do tar xzf $z; done
Outra possibilidade no zsh:
setopt extended_glob
zargs -n 1 -- *.tgz~Broad_hapmap3_r2_Affy6_cels_excluded.tgz -- tar xzf
Em ksh (mas não bash ou zsh, pois eles não suportam e padrões):
for z in @(*.tgz&!(Broad_hapmap3_r2_Affy6_cels_excluded.tgz); do tar xzf "$z"; done
Outra maneira no ksh:
( FIGNORE=Broad_hapmap3_r2_Affy6_cels_excluded.tgz;
for z in *.tgz; do tar xzf "$z"; done )
No bash:
( GLOB_IGNORE=Broad_hapmap3_r2_Affy6_cels_excluded.tgz;
for z in *.tgz; do tar xzf "$z"; done )
Em qualquer shell:
for z in *.tgz; do
[ "$z" = Broad_hapmap3_r2_Affy6_cels_excluded.tgz ] || tar xzf "$z"
done
Mais uma outra maneira estranha:
mv Broad_hapmap3_r2_Affy6_cels_excluded.tgz Broad_hapmap3_r2_Affy6_cels_excluded.tgz.not
for z in *.tgz; do tar xzf "$z"; done
mv Broad_hapmap3_r2_Affy6_cels_excluded.tgz.not Broad_hapmap3_r2_Affy6_cels_excluded.tgz
Se você também quiser agir em arquivos em subdiretórios, o find é a ferramenta natural a ser usada. Os exemplos recursivos abaixo excluem arquivos denominados Broad_hapmap3_r2_Affy6_cels_excluded.tgz
em qualquer subdiretório.
find . -name '*.tgz' -type f \
\! -name Broad_hapmap3_r2_Affy6_cels_excluded.tgz \
-exec tar xzf {} \;
Para uma travessia recursiva em zsh ou bash ≥4, você pode usar **
em padrões. Em zsh:
setopt extended_glob
zargs -n 1 -- **/*.tgz~**/Broad_hapmap3_r2_Affy6_cels_excluded.tgz -- tar xzf
Em bash ≥4:
shopt -s globstar
( GLOB_IGNORE=Broad_hapmap3_r2_Affy6_cels_excluded.tgz;
for z in **/*.tgz; do tar xzf "$z"; done )
Você pode até mesmo encontrar se não quiser uma travessia recursiva, embora não seja a maneira mais conveniente.
find *.tgz -type f \
\! -name Broad_hapmap3_r2_Affy6_cels_excluded.tgz \
-exec tar xzf {} \;
Para coisas pontuais como essa, eu apenas forcei:
for f in *.tgz; do
[[ "$f" != "Broad_hapmap3_r2_Affy6_cels_excluded.tgz" ]] && tar zxvf "$f"
done