使用通配符解压 *.tgz 文件的目录

使用通配符解压 *.tgz 文件的目录

我有一个看起来像这样的目录

$ 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

我想使用单个命令解压缩与扩展名 *.tgz 匹配的所有文件,但 Broad_hapmap3_r2_Affy6_cels_excluded.tgz 除外。

我可以

ls *.tgz | xargs -n1 tar zxvf

对于所有 *tgz 文件,但是排除其中一部分的好方法是什么?从网上阅读也许可以找到这种情况的指示,但这似乎有点矫枉过正。预先感谢。

附录:我也对不排除文件的问题的替代方法感兴趣。

答案1

在 zsh 中:

setopt extended_glob
for z in *.tgz~Broad_hapmap3_r2_Affy6_cels_excluded.tgz; do tar xzf $z; done

zsh 中的另一种可能性:

setopt extended_glob
zargs -n 1 -- *.tgz~Broad_hapmap3_r2_Affy6_cels_excluded.tgz -- tar xzf

在 ksh 中(但不是 bash 或 zsh,因为它们不支持 和 模式):

for z in @(*.tgz&!(Broad_hapmap3_r2_Affy6_cels_excluded.tgz); do tar xzf "$z"; done

ksh 中的另一种方式:

( FIGNORE=Broad_hapmap3_r2_Affy6_cels_excluded.tgz;
  for z in *.tgz; do tar xzf "$z"; done )

在bash中:

( GLOB_IGNORE=Broad_hapmap3_r2_Affy6_cels_excluded.tgz;
  for z in *.tgz; do tar xzf "$z"; done )

在任何外壳中:

for z in *.tgz; do
  [ "$z" = Broad_hapmap3_r2_Affy6_cels_excluded.tgz ] || tar xzf "$z"
done

还有另一种黑客方式:

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

如果您还想对子目录中的文件进行操作,那么 find 是自然而然的工具。下面的递归示例排除Broad_hapmap3_r2_Affy6_cels_excluded.tgz任何子目录中命名的文件。

find . -name '*.tgz' -type f \
       \! -name Broad_hapmap3_r2_Affy6_cels_excluded.tgz \
       -exec tar xzf {} \;

对于 zsh 或 bash ≥4 中的递归遍历,可以使用**in 模式。在 zsh 中:

setopt extended_glob
zargs -n 1 -- **/*.tgz~**/Broad_hapmap3_r2_Affy6_cels_excluded.tgz -- tar xzf

在 bash ≥4 中:

shopt -s globstar
( GLOB_IGNORE=Broad_hapmap3_r2_Affy6_cels_excluded.tgz;
  for z in **/*.tgz; do tar xzf "$z"; done )

如果您不想递归遍历,您甚至可以使用 find ,尽管这不是最方便的方法。

find *.tgz  -type f \
            \! -name Broad_hapmap3_r2_Affy6_cels_excluded.tgz \
            -exec tar xzf {} \;

答案2

对于像这样一次性的事情,我只会暴力破解:

for f in *.tgz; do 
   [[ "$f" != "Broad_hapmap3_r2_Affy6_cels_excluded.tgz" ]] && tar zxvf "$f"
done

答案3

你总是可以这样做:

ls *.tgz | grep -v Broad_hapmap3_r2_Affy6_cels_excluded.tgz | xargs -n1 tar zxvf

但我怀疑有人会发布一种更干净的方法,直接从 bash shell 执行此操作,而不需要在那里使用 grep。

相关内容