只有 tar 文件,没有目录

ate*_*iob 16 tar

我可能只能编写一个 shell 脚本来查找文件,然后将列表传递给 tar,但我想知道 tar 中是否已经有一个内置功能允许在单个命令行中执行此操作?

例如,我找到了--no-recursion开关,但是当我这样做时:

tar --no-recursion -cvf mydir.tar mydir
Run Code Online (Sandbox Code Playgroud)

它只归档目录中条目的名称(包括子目录!),但不归档任何文件。

我也试过:

 tar --no-recursion -cvf mydir.tar mydir/*
Run Code Online (Sandbox Code Playgroud)

但是,虽然它只存档文件,但它也存档子目录的名称

有没有办法只告诉 tar 文件,没有目录?

cam*_*amh 14

当您想使用findwith 时tar,最好的方法是使用cpio代替tarcpio可以写入 tar 存档,旨在从标准输入中获取要存档的文件列表。

find mydir -maxdepth 1 -type f -print0 | cpio -o -H ustar -0 > mydir.tar
Run Code Online (Sandbox Code Playgroud)

使用findandcpio是一种更 unix-y 的方法,因为您find可以使用它拥有的所有功能进行文件选择,然后cpio进行归档。值得学习这种简单的用法cpio,因为您会发现很容易解决在尝试时遇到的问题tar

  • 这对我来说比接受的答案要好得多。 (2认同)

Kev*_*vin 12

正如 camh 指出的那样,前面的命令有一个小问题,因为文件名太多,它会执行不止一次,后面的调用会默默地清除以前的运行。由于我们也没有压缩,我们可以追加而不是覆盖:

find mydir -maxdepth 1 -type f -print0 | xargs -0 tar Avf mydir.tar
find mydir -maxdepth 1 -type f -exec tar Avf mydir.tar {} +
Run Code Online (Sandbox Code Playgroud)

Iocnarz使用tar's--null-Toptions的答案也有效。如果您已经cpio安装,使用它的camh 答案也很好。如果您已经zsh并且不介意将它用于命令,Gilles 使用 zsh glob ( *(.))的答案似乎是最直接的。


关键是-maxdepth选项。最终答案,适当处理空格:

find mydir -maxdepth 1 -type f -print0 | xargs -0 tar cvf mydir.tar
Run Code Online (Sandbox Code Playgroud)

这也应该有效:

find mydir -maxdepth 1 -type f -exec tar cvf mydir.tar {} +
Run Code Online (Sandbox Code Playgroud)

  • 这两种情况都会导致多次调用 `tar`。`xargs` 和带有 `+` 变体的 `find` 都有可以传递给 tar 的最大参数数。这将导致第二次调用 tar 覆盖第一次的输出。 (4认同)
  • 扩展 xargs 限制,xargs 默认为最大 128KiB 命令行。如果文件列表较大,您会再次(或更多)调用命令 (tar),从而导致无提示数据丢失。您可以使用 `-x` 来强制 xargs 失败而不是丢失数据,虽然比静默数据丢失错误更好,但它仍然不理想。这种排序错误非常危险,因为一开始一切似乎都很好,但是随着文件列表随着时间的推移而增长,您开始触发它,并且在您尝试恢复备份之前可能不会注意到。那么为时已晚。 (2认同)