我想使用 gzip 命令行工具压缩文本文件保持原始文件。默认运行以下命令
gzip file.txt
结果会修改该文件并重命名它file.txt.gz
。我希望将这个新的压缩文件放入添加到现有的一个file.txt
。现在我正在使用以下命令来执行此操作
gzip -c file.txt > file.txt.gz
它有效,但我想知道为什么没有更简单的解决方案来完成这样的常见任务?也许我错过了这样做的选择?
答案1
对于 GNU gzip
1.6 或更高版本、FreeBSD 及其衍生版本或 NetBSD 的最新版本,请参阅唐克里斯蒂的回答。
对于任何版本,您都可以使用 shell 重定向,如下所示:
gzip < file.txt > file.txt.gz
当未给出任何参数时,gzip
读取其标准输入,对其进行压缩并将压缩版本写入其标准输出。作为一个额外的好处,当使用 shell 重定向时,您不必担心名为"--help"
or的文件"-"
(后一个仍然是 的问题gzip -c --
)。
另一个好处gzip -c file.txt > file.txt.gz
是,如果file.txt
无法打开,命令将失败,而不会创建空的file.txt.gz
(或覆盖现有的file.txt.gz
)并且gzip
根本不会运行。
与此相比的一个显着区别gzip -k
是,不会尝试将file.txt
的元数据(所有权、权限、修改时间、未压缩文件的名称)复制到file.txt.gz
.
此外,如果file.txt.gz
已经存在,它将默默地覆盖它,除非您noclobber
在 shell 中打开了该选项(set -o noclobber
例如在 POSIX shell 中)。
答案2
请注意,最近(2013 年 6 月)发布的gzip-1.6
“接受 --keep (-k) 选项,以与 xz、lzip 和 bzip2 等工具保持一致。使用此选项,gzip 在压缩或解压缩时不再删除指定的输入文件”。
手册页摘录:
-k --keep Keep (don't delete) input files during compression or decompression.
因此,从 开始1.6
,您可以使用-k
或--keep
保留原始文件:
gzip -k -- "$file"
$file
(请注意,如果是-
(gzip
解释为含义),它不起作用标准输入而不是名为 ) 的实际文件-
,在这种情况下,您必须将其更改为./-
)
那个选项是首先在 FreeBSD 实现中引入gzip
(在 2007 年的 FreeBSD 7.0 中)为了与bzip2
.这gzip
是基于 NetBSD 对 GNU 的重写gzip
。这-k
该选项最终于 2010 年重返 NetBSD。
答案3
从文档来看,似乎没有选项可以创建文件的副本。
您可以定义一个shell函数
gzipkeep() {
if [ -f "$1" ] ; then
gzip -c -- "$1" > "$1.gz"
fi
}
进而
gzipkeep file.txt
答案4
为了构建@Matteo的答案,您可以gzipkeep
通过将代码包围在for循环中来处理通配符,保留gzip在缺少该标志的系统上一次处理多个文件的能力-k
(这是一个巨大的优势,否则,对于-k
)。我还使它变得详细,以便我可以看到每个尝试文件的状态:
gzipkeep() {
for file in "$@"; do
if [ -f "$file" ] ; then
gzip -cv9 -- "$file" > "$file.gz"
fi
done
}
然后用通配符运行它。例如:
gzipkeep images/*.svg