*.vtu
我的意思是在 bash 中对给定目录下所有深度的所有文件进行 gzip 压缩。我在深度 1 和 2 下有这样的文件./
。我设法这样做了
$ gzip -v $(find . -name "*.vtu")
我还可以使用find ... -exec
,和其他组合(见下文)。
有没有办法仅使用 gzip 功能来实现这一点(-r
这是我的候选人)?
我期望
$ gzip -r -v "*.vtu"
其中模式不会因外壳而扩展,而是会扩展gzip
(并以某种方式产生我的预期结果!),可以解决这个问题,但我gzip: ...: No such file or directory
尝试了所有组合都失败了。我发现以下情况:
- 与
shopt -s globstar
(来自这里),这个命令gzip -v **/*.vtu
似乎完全符合我的要求。 - 如果
shopt | grep globstar
给出globstar off
,则上述命令不起作用。在这种情况下,我可以使用gzip -v */*.vtu
,但它仅适用于深度为 1 的文件。gzip -v */*/*.vtu
深度为 2 的文件也同样如此。
无论如何,我没有发现 flag 的作用/用处是什么-r
。
有关的:
答案1
不,gzip 无法做到这一点,-r
它只是意味着“进入子目录”,但没有“进入子目录,然后查找与此 glob 匹配的文件”的选项。 glob 的扩展*.vtu
发生在grep
启动之前,并且由 shell 而不是处理grep
,因此给出了一个特定的文件列表:当前目录中grep
匹配的文件。*.vtu
所以是的,这globstar
是你最好的选择。至于的用法-r
,在中进行了解释man gzip
:
-r --recursive
Travel the directory structure recursively. If any of the file
names specified on the command line are directories, gzip will
descend into the directory and compress all the files it finds
there (or decompress them in the case of gunzip ).
So 的意思是“如果是目录,则gzip -r foo
进入该目录并对其中的文件进行 gzip 压缩”。如果同时匹配文件和目录,例如,如果您在运行的目录中同时拥有和,那么的内容也会被压缩。如果没有它,您将得到。foo
foo
foo
file.vtu
my.vtu/
gzip
my.vtu
my.vtu is a directory -- ignored
其他选项包括:
find . -name "*.vtu" -exec gzip {} +
压缩所有匹配的文件。gzip **/*.vtu
与globstar
设置。find . -name "*.vtu" | xargs gzip
(只要你的名字合理并且不包含换行符)find . -name "*.vtu" -print0 | xargs -0 gzip
(如果您的文件名可以包含换行符)
答案2
后terdon 的回答,经过一番修改后,我得出结论,该-r
工作方式如下:
- 如果匹配的是一个文件(仅在当前目录中)则执行
gzip
。 - 如果匹配的是目录,则进入该目录,然后执行
gzip -r *
。
对我来说,这非常奇怪(因此我从未想象过这是它的工作原理)。例如,如果./
我有
foo
foo.vtk
test.vtk/
test.vtk/another.vtk/
test.vtk/another.vtk/cake.vtk
test.vtk/another.vtk/dow.txt
test.vtk/cake.vtk
test.vtk/dow.txt
test.vtk/this/
test.vtk/this/cake.vtk
test.vtk/this/dow.txt
命令gzip -r -v *.vtk
将对除 之外的所有文件进行 gzip 压缩。所有子目录(depth=1) 和(depth>1)中的./foo
所有文件(不仅仅是)都将被压缩。*.vtk
*.vtk
*
gzip
答案3
这不是您问题的确切答案,但您可以使用xargs
它,它允许您并行运行多个gzip
进程,例如
find -name '*.vtk' -print0 | xargs -r0n1 -P$(nproc) gzip
- 查找文件
- 匹配
*.vtk
,引用,所以它不会被 shell 扩展 - 打印由 NUL 字节分隔的文件名(以便具有明确的分隔符)
- 匹配
- 将文件列表提供给
xargs
- 如果列表为空则不运行(
-r
),因为 gzip 会使用 stdin - 使用 NUL 作为分隔符 (
-0
) - 每次调用使用一个文件名
gzip
(-n1
) - 根据命令输出的 CPU
-P
数量,并行运行尽可能多的进程( )nproc
gzip
对每个输入运行命令
- 如果列表为空则不运行(