是否可以使用zip命令将所有文件压缩到给定目录中?我听说过使用*.*,但我也希望它也可用于无扩展名的文件。

评论

您是否尝试过从所需目录向上导航并执行zip myarch.zip mydir / *?

或更好的zip -r myarch.zip mydir / *

或更好的zip -r myarch.zip mydir

*。*表示任何带点的文件。在cp / m和dos中,所有文件都有一个点,这使您键入它(不能*)。因此人们开始将*。*视为所有文件。最终,Microsoft添加了长文件名,该文件名可以包含零个或多个点。要查找Windows上带有点的文件,必须键入*。*。*。

#1 楼

您可以只使用*;不需要*.*。文件扩展名在Unix上并不特殊。 *匹配零个或多个字符,包括一个点。因此它匹配foo.png,因为它是零个或多个字符(准确地说是七个字符)。

请注意,默认情况下*不匹配以点开头的文件(*.*都不匹配)。这通常是您想要的。如果不是,请在bash中使用shopt -s dotglob(但仍会排除...)。其他shell包含点文件的方式有所不同(或根本没有)。或者,zip还具有-r(递归)选项,可立即执行整个目录树(而不必担心点文件)问题):

zip -r myfiles.zip mydir


其中mydir是包含文件的目录。请注意,生成的zip将包含目录结构以及文件。正如peterph在他的评论中指出的那样,这通常被视为一件好事:解压缩zip会将所有提取的文件整齐地存储在一个子目录中。

还可以告诉zip不要使用以下命令存储路径-j / --junk-paths选项。

zip命令随附的文档向您介绍了其所有(许多)选项;键入man zip以查看该文档。这不是zip独有的。您可以通过这种方式获取大多数命令的文档。

评论


您可能想补充一点,将归档文件中的所有内容都包含在顶层目录中是一种好习惯,这样一来,提取时就不会污染当前目录。

–彼得
2012年11月28日在16:54

@peterph完成了。恐怕这在zip文件中比在tarfile中要少一些惯例。

–德罗伯特
2012年11月28日在16:59

不幸的是。可能是由于Windows继承了Windows的传统,而Windows则继承了使用源代码的传统。

–彼得
2012年11月28日17:03



请记住,* shell-globbing不包含点文件(即,以。开头的文件名)。这是按名称压缩整个目录的另一个优点。

–mrb
2012年11月28日17:29



但是使用-r包括目录本身,这破坏了我的工作。不*包括。和..?

–tkbx
2012年11月28日17:30

#2 楼

就我而言,我想将每个文件压缩到自己的存档中,所以我做了以下操作(在zsh中):

$ for file in *; do zip ${file%.*}.zip $file; done


评论


这里没有mkv?同样,这里没有什么特别针对zsh。您将希望正确地引用任何包含文件名的变量,因此在“ $ {file%。*}。zip”“ $ file”上加上两个变量的双引号。

–tripleee
17年1月30日,11:08



@tripleee首先,感谢您指出我对mkv的错误引用。其次,与bash不同,在zsh中不需要引号。这就是为什么我指定这是zsh的命令的原因。

–拉登·罗斯伯勒(Radon Rosborough)
17年1月30日在16:20

用“&”代替最后一个分号可能会大大加快速度(如果目录中的文件数量合理...)。否则找到。 -类型f -maxdepth 1 -print0 | xargs -r0 -n1 -P64 -I {} bash -c'f =“ {}”; zip“ $ {f%。*}。zip”“ $ f”'(根据您的CPU线程调整了-P ...)(许多GNU依赖项...)

– Gert van den Berg
18年5月18日在17:30



#3 楼

另一种方法是使用find和xargs :(这可能在zip中包含一个“。”目录,但仍应正确提取。在我的测试中,zip在压缩前将点删除了)。
find . -type f -exec zip zipfile.zip {} +

(如果您的+版本不支持exec的\;结尾,则可以将find替换为+。尽管这样会变慢...)

默认情况下,它将包括所有子项目录。在GNU上找到-maxdepth可以防止这种情况。

评论


(与使用*的解决方案不同,这将包括点文件,并且如果目录中的文件过多,将不会掉线)

– Gert van den Berg
18年5月17日在16:04

#4 楼

另一种(慢速)方法(一次将一个文件添加到zip文件中):

for f in * .[^.]*; do
    [ -r "$f" ] || continue # Skip directories or non-existant files (Probably ".[^.]*" if directory has no dotfiles). Using -e will allow directories to be used as well
    zip zipfile.zip "$f" # If directories are included, you probably want to add -r
done


这有*的点文件问题(已添加解决方法),并且将是每个文件一次启动zip,然后将其添加到存档中。在bash中,它将处理大量文件。

比大多数其他方法要慢,但相对简单。

评论


我要说的是,这比公认的答案要简单得多,但速度较慢,这提示了一个问题:“为什么有人会这样做?”。如果您可以回答该问题,建议您将上下文放在您的回答中,否则我认为这对于已经有好的回答的旧问题是一个不好的回答。

–世纪
18年5月17日在16:21



@Centimane:我注意到了局限性。我觉得这具有教育意义。 (如果不跳过目录,则非常简单)。如果您想要使用(标准)外部工具更快的答案,则我的其他答案可以解决。 (删除了dotfiles处理(这会影响正确性,而不会在问题中提及它们的缺失),我觉得这很优雅):for in in *; zip zip.zip“ $ f”;完成

– Gert van den Berg
18年5月18日在17:09

请注意,可接受的答案不使用外部命令,并且会更快。在什么情况下此答案有用?

–世纪
18年5月18日在19:00

@Centimane使用tar时,文件数量超过bash可以作为参数传递的数量。 (find + xargs更好,因为循环更容易...)。这是对这个问题的(唯一)答案。当然,这不是最佳答案。 (如果某人的情况略有不同-例如,要tar文件中的任何目录,非最佳答案对于类似问题仍然有用)

– Gert van den Berg
18年5月18日在22:18