我有以下目录结构:
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
命令将排除文件包含1
或2
在路径和目录中。
答案2
使用 GNU tar,您还可以使用该--exclude
选项根据名称排除文件。
$ tar --exclude "*1*" --exclude "*2*" -cvf foo.tar test/
test/
test/3/
还有-X
or --exclude-from
which 需要一个文件来读取排除模式。
尽管 as find -not -path "*1*"
,这也会排除名称包含1
或的文件2
。仅跳过目录其名称与模式匹配,使用find -prune
和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
(至少 GNU tar 和 FreeBSD tar 有--no-recursion
)