如何使用tar命令排除特定文件?

时间:2016-02-16 17:21:32

标签: linux tar

假设我有以下目录结构

dir/
├── subdir
│   ├── dir
│   │   └── TODO.txt
│   └── TODO.txt
└── TODO.txt

我希望在Linux上使用命令dir/递归地将tar捆绑到一个tarball中,但我想要排除根TODO.txt 。如何用相对路径指定它?

尝试#1

tar -czf dir.tar.gz  dir/ --exclude='TODO.txt'

不起作用:它在最终的tarball中删除每个 TODO.txt:

dir/
└── subdir
    └── dir

尝试#2

tar -czf dir.tar.gz  dir/ --exclude='dir/TODO.txt'

这也失败了,因为dir子目录也与此模式匹配。由此产生的tarball包含

dir/
└── subdir
    ├── dir
    └── TODO.txt

我有什么方法可以准确指出我想用相对路径排除根TODO.txt吗?

2 个答案:

答案 0 :(得分:0)

来自@arkascha的答案:

find dir/ -type f | grep -v "^dir/TODO.txt" > files.txt

然后

tar -czf dir.tar.gz -T files.txt

从第一行开始,有两个要注意的技巧:

  1. -type f选项。如果没有,目录将包含在find的结果中。这很糟糕,因为它会在文件层次结构中包含每个文件的深度次数。
  2. ^正则表达式中的grep:它确保我们从文件层次结构的开头排除模式

答案 1 :(得分:0)

不要使用 dir/ 来命名您的传输,而是将其 cd 到 dir,然后将其命名为 .。文件夹名称 . 以后永远不会出现在任何文件路径中,因此它可以作为一个强大的锚点。然后使用 --transform=,让存档中的路径以 dir/ 开头。

演示

无过滤器:

$ tar -czf dir.tar.gz -v dir
dir/
dir/TODO.txt
dir/subdir/
dir/subdir/TODO.txt
dir/subdir/dir/
dir/subdir/dir/TODO.txt

cd 进入 dir,将其命名为 .

$ tar -czf dir.tar.gz -v -C dir .
./
./TODO.txt
./subdir/
./subdir/TODO.txt
./subdir/dir/
./subdir/dir/TODO.txt

排除,锚定在 . 上:

$ tar -czf dir.tar.gz -v -C dir --exclude='./TODO.txt' .
./
./subdir/
./subdir/TODO.txt
./subdir/dir/
./subdir/dir/TODO.txt

在存档内将 . 改回 dir(--show-transformed-names 使 tar 在进入存档时显示名称):

$ tar -czf dir.tar.gz -v -C dir --exclude='./TODO.txt' --transform='s/^\./dir/g' --show-transformed-names .
dir/
dir/subdir/
dir/subdir/TODO.txt
dir/subdir/dir/
dir/subdir/dir/TODO.txt