对于具有指定过滤器的指定目录中的所有文件(png|gif|jpe?g)
(!使用\0
分隔符以避免文件名带有空格问题),我想查看“优化”webp
文件是否存在,以及是否存在不是,转换它。
我知道接下来的内容可以优化等等,但我只是想让它发挥作用。
如果您有更好的解决方案(有解释!)当然,这也很有趣。
IFS= readarray -t -d '' tab < <(find . -type f -print0 | grep -zZE "(png|gif|jpe?g)$") && for f in "${tab[@]}"; do if [ ! -f "$f.webp" ]; then cwebp -q 80 "$f" -o "$f.webp"; fi done
这就是我所做的:我正在通过readarray
所有找到的与我的模式匹配的文件创建一个数组。然后我对它们进行循环,测试文件是否存在。如果没有,我称cwebp -q 80 "$f" -o "$f.webp";
This one does not work 并出现以下错误。为什么?
Error! Could not process file ./08/10700_header.jpg
Error! Cannot read input picture file './08/10700_header.jpg'
Error! Could not process file ./08/205790_header.jpg
Error! Cannot read input picture file './08/205790_header.jpg'
答案1
bash 中更好的解决方案:你实际上不需要找到:
shopt -s extglob # extended pattern match, you likely already have it set
shopt -s globstar # extended directory level search ('**' matches any directory level)
for f in **/*.@(jpg|jpeg|png|gif)
do
[[ -f "$f.webp" ]] || cwebp -q 80 "$f" -o "$f.webp"
done
要运行,parallel
我们必须删除已经完成的文件,以便我们可以cwebp
直接调用。一种方法是使用 webp 文件列表过滤文件列表:
printf '%s\n' **/*.@(jpg|jpeg|png|gif) \
| grep -vf <(printf '%s\n' **/*.webp | sed 's/\.webp$//') \
| parallel -i cwebp -q 80 {} -o {}.webp
慢动作:
printf '%s\n' **/*.@(jpg|jpeg|png|gif)
生成所有可能候选者的列表作为流(因为这是printf
内置的 i,在 bash 中它不受命令行约束)grep -vf <(printf '%s\n' **/*.webp | sed 's/\.webp$//')
从该列表中删除所有已关联的文件.webp
(通过列出*.webp
文件、截断其扩展名并将结果用作grep
模式列表)parallel -i cwebp -q 80 {} -o {}.webp
将结果提供给并行执行。
请注意,由于parallel
似乎没有参数来接受以 null 结尾的输入,因此您只需要希望没有奇怪的文件名即可。
预过滤技术也可用于非并行情况。
答案2
我不完全确定是什么产生了您显示的错误或原因,但大概是在cwebp
查找您提供的路径名时遇到了问题。
我会让find
找到相关文件并执行循环,而不是使用grep
临时数组:
find . \( -name '*.png' -o -name '*.gif' -o -name '*.jpg' -o -name '*.jpeg' \) \
-type f -exec sh -c '
for pathname do
[ -f "$pathname.webp" ] && continue
cwebp -q 80 "$pathname" -o "$pathname.webp"
done' sh {} +
在这里,我用作find
内联脚本的一种路径名生成器sh -c
。内联脚本批量获取路径名并循环它们。对于每个给定的路径名,如果相应的.webp
文件存在,则循环跳到下一个路径名。否则,cwebp
将调用该命令。
这避免了奇怪的文件或目录名的问题,并且可以移植到任何已cwebp
安装的系统(find
命令本身是标准的,内联脚本也是如此)。
也可以看看 ”了解“find”的 -exec 选项" 有关-exec sh -c '...' sh {} +
语法的更多信息。
如果这仍然不起作用,您可能需要调查报告的图像文件以确保它们确实是有效的图像文件。