TL;DR(没有./ 也没有./file1!)
find /my/dir/ -printf "%P\n" | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -
在某些条件下(仅归档文件、目录和符号链接):
find /my/dir/ -printf "%P\n" -type f -o -type l -o -type d | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -
说明
不幸的是,以下内容在存档中包含一个父目录./:
tar -czf mydir.tgz -C /my/dir .
您可以使用--transform 配置选项将所有文件移出该目录,但这并不能摆脱. 目录本身。驯服命令变得越来越困难。
您可以使用$(find ...) 将文件列表添加到命令中(如magnus' answer),但这可能会导致“文件列表太长”错误。最好的方法是将它与 tar 的 -T 选项结合起来,像这样:
find /my/dir/ -printf "%P\n" -type f -o -type l -o -type d | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -
基本上它的作用是列出目录下的所有文件 (-type f)、链接 (-type l) 和子目录 (-type d),使用 -printf "%P\n" 使所有文件名相对,然后将其传递给 tar命令(它使用 -T - 从 STDIN 获取文件名)。需要 -C 选项,以便 tar 知道具有相对名称的文件所在的位置。 --no-recursion 标志是为了使 tar 不会递归到它被告知归档的文件夹(导致重复文件)。
如果你需要对文件名做一些特殊的事情(过滤、跟随符号链接等),find 命令非常强大,你可以通过删除上述命令的tar 部分来测试它:
$ find /my/dir/ -printf "%P\n" -type f -o -type l -o -type d
> textfile.txt
> documentation.pdf
> subfolder2
> subfolder
> subfolder/.gitignore
例如要过滤PDF文件,添加! -name '*.pdf'
$ find /my/dir/ -printf "%P\n" -type f ! -name '*.pdf' -o -type l -o -type d
> textfile.txt
> subfolder2
> subfolder
> subfolder/.gitignore
非 GNU 查找
该命令使用printf(在GNU find 中可用)告诉find 使用相对路径打印其结果。但是,如果您没有 GNU find,这可以使路径相对(使用 sed 删除父级):
find /my/dir/ -type f -o -type l -o -type d | sed s,^/my/dir/,, | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -