我通常这样做:
tar -czvf my_directory.tar.gz my_directory
如果我只想在my_directory中包含所有内容(包括任何隐藏的系统文件),而不包括目录本身,该怎么办?我不想:
my_directory
--- my_file
--- my_file
--- my_file
我想要:
my_file
my_file
my_file
我通常这样做:
tar -czvf my_directory.tar.gz my_directory
如果我只想在my_directory中包含所有内容(包括任何隐藏的系统文件),而不包括目录本身,该怎么办?我不想:
my_directory
--- my_file
--- my_file
--- my_file
我想要:
my_file
my_file
my_file
当前回答
tar -C my_dir -zcvf my_dir.tar.gz `ls my_dir`
其他回答
使用pax。
Pax是一个被弃用的包,但它以一种简单的方式完美地完成了这项工作。
pax -w > mydir.tar mydir
如果使用bash,这可能是最简单的答案。 使用shopt -s dotglob, bash命令将:
不包括根目录。 将包含根目录中的隐藏文件。
cd my_directory
shopt -s dotglob
tar -czvf ../my_directory.tar.gz *
shopt -u dotglob
(来自https://stackoverflow.com/a/9776491/7726468)
测试这个解决方案:
命令
创建标准归档文件。
find my_directory/ -maxdepth 1 -printf "%P\n" | tar -cvf my_archive.tar -c my_directory/ - t -
打包文件和dirs文件在存档的根目录下,没有路径信息,较深的文件有相对路径。 没有奇怪的样子。”/'放在文件和dirs前面。(“。/文件”) 没有特殊文件。’。
似乎需要另一个工具,如find或ls (ls -A -1)来实现这些目标,而tar仅使用其参数无法根据这样的要求选择文件并创建存档。
使用上述命令创建一个tar归档文件,可以进一步处理或交付给某人,而不需要看起来奇怪或需要解释或工具来解压缩。
参数描述
maxdepth 1 最多下降1级-无递归。 printf 在标准输出上打印格式 %P文件的名称,删除它所在的起始点的名称。 \ n换行符 Printf不会在字符串的末尾添加换行符。必须加在这里
沥青: -C DIR,——directory=DIR 更改目录
-T FILE,——files-from=FILE 获取要从FILE中提取或创建的名称 - 上面的FILE是来自管道的标准输入
对其他解决方案的评论。
The same result might be achieved using solution described by @aross. The difference with the solution here is in that which tool is doing the recursing. If you leave the job to find, every filepath name, goes through the pipe. It also sends all directory names, which tar with --no-recursion ignores or adds as empty ones followed by all files in each directory. If there was unexpected output as errors in file read from find, tar would not know or care what's going on. But with further checks, like processing error stream from find, it might be a good solution where many options and filters on files are required. I prefer to leave the recursing on tar, it does seem simpler and as such more stable solution. With my complicated directory structure, I feel more confident the archive is complete when tar will not report an error.
@serendrewpity提出的另一个使用find的解决方案似乎很好,但它在带有空格的文件名上失败了。不同之处在于$()子shell提供的find输出是空格分隔的。可以使用printf添加引号,但这会使语句更加复杂。
当使用../my_archive.tar作为tar路径时,没有理由先cd到my_directory,然后再返回,因为tar有-C DIR,——directory=DIR命令,这就是为了这个目的。
使用。(dot)将包含圆点
使用*将让shell提供输入文件列表。可以使用shell选项来包含点文件。但这很复杂。该命令必须在允许的shell中执行。启用和禁用必须在tar命令之前和之后执行。如果根目录的未来存档包含太多的文件,它将失败。
最后一点也适用于所有不使用管道的解决方案。
大多数解决方案是创建一个目录,里面是文件和dirs。这几乎是人们所不希望看到的。
这个答案在大多数情况下都适用。但是请注意tar文件中的文件名是如何存储的,例如,./file1而不仅仅是file1。我发现,在使用此方法操作作为BuildRoot包文件的tarball时,这会导致问题。
一种解决方案是使用一些Bash glob列出除..之外的所有文件。是这样的:
tar -C my_dir -zcvf my_dir.tar.gz .[^.]* ..?* *
这是我从这个回答中学到的一个技巧。
现在如果没有文件匹配,tar将返回一个错误。?*或。[^。*,但它仍然可以工作。如果错误是一个问题(你正在检查一个脚本是否成功),这是有效的:
shopt -s nullglob
tar -C my_dir -zcvf my_dir.tar.gz .[^.]* ..?* *
shopt -u nullglob
虽然现在我们正在处理shell选项,但我们可能会决定使用* match隐藏文件会更整洁:
shopt -s dotglob
tar -C my_dir -zcvf my_dir.tar.gz *
shopt -u dotglob
这可能不适用于当前目录下的shell glos *,所以,或者,使用:
shopt -s dotglob
cd my_dir
tar -zcvf ../my_dir.tar.gz *
cd ..
shopt -u dotglob
cd my_directory
tar zcvf ../my_directory.tar.gz *