当输出馈送到 tar 时,“find”中的过滤器将被忽略

当输出馈送到 tar 时,“find”中的过滤器将被忽略

我有以下目录结构:

test/
test/1/
test/foo2bar/
test/3/

我想压缩目录“test”,不包括子目录中的所有内容(深度未预定义),其中包括字符串“1”或“2”。在 bash shell 中,我想使用寻找并将其输出馈送到柏油。我首先测试寻找

find test/ -not -path "*1*" -not -path "*2*"

输出:

test/
test/3

伟大的。所以我将它与柏油

find test/ -not -path "*1*" -not -path "*2*" | tar -czvf test.tar.gz --files-from -

输出:

test/
test/3/
test/1/
test/foo2bar/
test/3/

事实上,“test/1”和“test/foo2bar”都存在于存档中。如果这些参数不应该出现在 find 输出中,为什么要传递给 tar?

答案1

为了扩展 @cuonglm 所说的内容,tar默认情况下是递归操作的。如果你给它传递一个目录名,它就会归档内容该目录的。

您可以修改find命令以仅返回文件名,而不返回目录...

find test/ -type f -not -path "*1*" -not -path "*2*" |
tar -czvf test.tar.gz --files-from -

您可以使用该--no-recursion标志来tar

find test/ -not -path "*1*" -not -path "*2*" | 
tar -czvf test.tar.gz --no-recursion --files-from - 

结果是:

test/
test/3/

--no-recursion标志特定于 GNU tar。如果您正在使用其他功能,请查阅相应的手册页以查看是否有类似的功能可用。

请注意,您的find命令将排除文件包含12在路径和目录中。

答案2

使用 GNU tar,您还可以使用该--exclude选项根据名称排除文件。

$ tar --exclude "*1*" --exclude "*2*" -cvf foo.tar  test/
test/
test/3/

还有-Xor --exclude-fromwhich 需要一个文件来读取排除模式。


尽管 as find -not -path "*1*",这也会排除名称包含1或的文件2。仅跳过目录其名称与模式匹配,使用find -prunetar --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

(至少 GNU tar 和 FreeBSD tar 有--no-recursion

相关内容