请原谅这个最基本的问题,但是我在 stack exchange 上找不到直接的答案或简单的例子。
假设我有一个文件夹,我想将其压缩成一个 zip 文件,以便与我那些讨厌的 Windows 朋友共享(否则我就用完tar
了)。它看起来像这样:
.
├── file1.txt
├── file2.txt
├── file3.txt
├── file.jpg
└── test.jpg
假设我已经zip
安装:
sudo apt-get install zip
我看到man zip
它允许我使用文件列表:
-@ 文件列表。如果文件列表指定为 -@ [MacOS 上不适用],zip 将从标准输入而不是命令行获取输入文件列表。例如,
zip -@ foo
所以我创建了zip.lst
如下所示的内容:
cat zip.lst
file1.txt
file2.txt
file3.txt
file.jpg
test.jpg
现在我尝试了:
zip -@ zip.lst
但它除了在控制台上创建一个空行外什么也没做。我可以继续按Enter,它只是继续创建更多空行,而似乎没有执行命令。经过一番搜索,我意识到我需要按Ctrl+来终止输入D
但现在我收到此错误:
zip warning: missing end signature--probably not a zip file (did you
zip warning: remember to use binary mode when you transferred it?)
zip warning: (if you are trying to read a damaged archive try -F)
zip error: Zip file structure invalid (zip.lst)
什么!?我的简单列表怎么不是“有效的文件结构”?返回手册获取更多信息,然后我仔细查看:
如果文件列表指定为 -@...
所以我尝试不用-@
,这样至少可以立即处理,而不必按Ctrl+ D,但我只剩下同样的错误。
幸运的是,我找到了一条评论在一个几乎不相关的问题的答案上,我意识到我需要明确命名 zip 文件。出现此错误是因为默认情况下它试图创建一个名为 的 zip 文件zip.lst
。但由于这是我的列表的名称,人们可能会认为它只会覆盖它,但不,它实际上是在尝试更新它。由于列表显然不是 zip 文件,我们得到了无效文件结构错误,现在很清楚为什么它说“可能不是 zip 文件”。所以我尝试了:
zip files.zip zip.lst
adding: zip.lst (deflated 35%)
尤里卡!我可以看到 zip 文件已创建并且我的文件夹现在包含以下内容:
.
├── file1.txt
├── file2.txt
├── file3.txt
├── file.jpg
├── files.zip
├── test.jpg
└── zip.lst
但在庆祝之前,让我们先确认一下 zip 文件的内容:
unzip -l files.zip
Archive: files.zip
Length Date Time Name
--------- ---------- ----- ----
48 2016-05-24 15:30 zip.lst
--------- -------
48 1 file
不!嗯,实际上从标准用法来看这是有道理的,因为它只是压缩了我提供的一个列表文件。最后我再次尝试,-@
但得到了相同的结果。
我究竟做错了什么?
顺便说一句,我知道我可以使用 GUI 并用鼠标来完成,但我需要编写脚本,而且一般来说,当我知道自己在做什么时,在 CLI 上的速度会更快。
答案1
使用文件<
重定向
zip files.zip -@ < zip.lst
或者你可以跳过列表,直接使用
zip files.zip *.txt *.jpg
谢谢钢铁司机
历史答案
我很高兴我可以自己回答我的问题因为我想把我内心的挣扎记录下来,希望那些跟随我的泪水的人可以通过搜索一些关键词来避免这种情况。
最终我发现正确答案,但它被发布到错误的问题。
需要澄清的几点:
- 该手册并不是指文件中的文字列表,而是指在控制台上列出文件。
- 可以理解的是,有人可能会误以为这是
foo
指文件列表,但它实际上是指输出 zip 文件的名称。 - 示例中省略了文件列表,因为它使用了开关
-@
,这表明它“从标准输入而不是从命令行“
了解了这一点,我们现在就可以采取各种方法来实现目标。
首先使用我们创建的文件列表,我们可以读出列表cat
并使用管道将输出重定向到 zip 作为标准输入:
cat zip.lst | zip -@ files.zip
adding: file1.txt (stored 0%)
adding: file2.txt (stored 0%)
adding: file3.txt (stored 0%)
adding: file.jpg (stored 0%)
adding: test.jpg (stored 0%)
对于每个文件来说,看到这一点adding: ...
无疑是一个好兆头,但是我们之前已经抱有希望,所以让我们确认一下:
unzip -l files.zip
Archive: files.zip
Length Date Time Name
--------- ---------- ----- ----
0 2016-05-24 14:54 file1.txt
0 2016-05-24 14:54 file2.txt
0 2016-05-24 14:54 file3.txt
0 2016-05-24 15:00 file.jpg
0 2016-05-24 14:59 test.jpg
--------- -------
0 5 files
甜的!但无论如何,谁会想创建一个一次性使用的列表呢?这是解决这一特定情况的糟糕迂回方法。最好从中获取列表ls
并将其传递给 zip:
ls | zip -@ files.zip
adding: file1.txt (stored 0%)
adding: file2.txt (stored 0%)
adding: file3.txt (stored 0%)
adding: file.jpg (stored 0%)
adding: test.jpg (stored 0%)
太棒了!现在让我们创建具有强大功能的过滤器,grep
例如压缩 jpg:
ls | grep .jpg | zip -@ images.zip
adding: file.jpg (stored 0%)
adding: test.jpg (stored 0%)
或者仅以“file”开头的文件
ls | grep file. | zip -@ files.zip
adding: file1.txt (stored 0%)
adding: file2.txt (stored 0%)
adding: file3.txt (stored 0%)
adding: file.jpg (stored 0%)
答案2
具有最大压缩级别的最简单命令
zip -9 -r filename.zip /path/to/dir singlefile.jpg