我有一个充满文件的目录*.CLM_01
。我想创建 1 个 zip 文件,其中包含文件内值为“005010X222”的所有文件。基本上,有一些文件包含“005010X223”,我想从 zip 中排除它们。它们是互斥的。这些值位于文件的数据中,而不是文件名中。
我尝试了这个,但它仍然将所有文件压缩到 1 个 zip 文件中
for f in *.CLM_01; do zip -ur test.zip $f | grep "005010X222" $f ; done
答案1
与zsh
GNUgrep
或兼容:
zip file.zip ${(0)"$(grep -l --null 005010X222 ./*.CLM_01)"}
如果您grep
不使用 a --null
,但您可以保证所有文件名都不包含换行符:
zip file.zip ${(f)"$(grep -l 005010X222 ./*.CLM_01)"}
对于其他类似 POSIX 的 shell,您可以使用 split+glob 运算符执行相同的操作:
IFS='
' # split on newline
set -o noglob # disable glob
zip file.zip $(grep -l 005010X222 ./*.CLM_01)
如果有bsdtar
,您还可以使用以下命令在其标准输入上传递以空分隔的文件列表--null -T -
:
grep -l --null 005010X222 ./*.CLM_01 | bsdtar --null -T - -acf file.zip
GNU 实现还可以通过以下方式自行递归grep
查找文件:*.CLM_01
grep --include='*.CLM_01' -rl --null 005010X222 . |
bsdtar --null -T - -acf file.zip
该解决方案不受传递给命令的参数数量限制的影响,因为文件路径不会作为参数传递给grep
or bsdtar
,但请注意,与上面基于 glob 的解决方案相反,它还会考虑隐藏文件。
对于 GNU grep
,另请参阅grep -L 005010X223
列出执行以下操作的文件不是包含 005010X223 而不是grep -l 005010X222
列出包含 005010X222 的那些。
答案2
find
与安静测试一起使用grep
:
find -name '*CLM_01' -exec grep -q '005010X222' {} \; -print0 | xargs -0 zip -u all_files.zip +
-q
ingrep
是安静选项,仅在匹配时成功(退出代码 0)。
最好也用于-u
以防需要多次调用的zip
情况。xargs
zip