使用 bash 通过 imageOptim 进行图像优化。如何获取整个批次的摘要,而不是一张图像

使用 bash 通过 imageOptim 进行图像优化。如何获取整个批次的摘要,而不是一张图像

我在用图像优化优化我的服务器上的图像。

我花了很长时间才学会基本的 Bash 脚本,以便能够优化我所有一级目录中的所有图像。我的脚本如下所示,从功能角度来看,它完全符合我的要求:

for dir in mydir/*/
do
    sudo jpegoptim --strip-all -t "$dir"*.jpg
done

这个问题很不美观。当我运行脚本时,它输出以下内容:

mydir/dir_1/img_1.jpg axb 24bit N JFIF  [OK] 2234 --> 1861 bytes (16.70%), optimized.
...
mydir/dir_1/img_16.jpg axb 24bit N JFIF  [OK] 2234 --> 1861 bytes (16.70%), optimized.
Average compression (16 files): 7.26% (8k)
mydir/dir_2/img_1.jpg axb 24bit N JFIF  [OK] 2234 --> 1861 bytes (16.70%), optimized.
...
mydir/dir_2/img_6.jpg axb 24bit N JFIF  [OK] 2234 --> 1861 bytes (16.70%), optimized.
Average compression (6 files): 7.26% (8k)

它输出该行,Average compression (6 files): 7.26% (8k)因为我用该标志要求提供摘要-t。但我不想获取有关每个单独图像的所有信息。当我尝试使用-t -q-tq或抑制它时-q -t(我尝试了所有方法,因为我不确定这是否重要),它根本没有显示任何信息。

理想情况下,我只想看到一个数字——我节省了多少尺寸。

因为这是我的第一个 bash 脚本(我花了一个小时来解决那个循环:-(),我的技能目前还不足以解决我的问题。

答案1

您可以使用find和尝试这个单行代码perl

sudo find . -type d -exec  sh -c "./jpegoptim --strip-all -t {}/*.jpg" \; | perl -e '@a=<>; $a=join("", @a); @b = $a =~ /%\s+\((\d+)k\)/g; foreach my $n (@b) {$sum = $sum + $n}; print "Total saved ${sum}k\n"'

当然,您需要复制到jpegoptim启动命令的目录中。find

实际上不需要 bash 循环,find可以用类型过滤目录-d

perl部分将仅解析“%(每个目录保存的大小k)”并将所有值相加,然后仅打印一行总和。


  • find . -type d仅返回目录。
  • -exec <command> \;将为每个目录启动给定的命令
  • sh -c ""是必需的,因为我们需要一个 shell 来解释 *.jpg 通配符。
  • 整个输出通过管道传输|到 perl
  • perl 首先使用 stdin(<>,菱形运算符)@a 创建一个数组。
  • 然后连接成一个字符串,$a
  • @b = $a =~ /%\s+\((\d+)k\)/g将使用正则表达式将平均压缩摘要行中包含的所有匹配的字符串放入数组@b中
  • 最后foreach my $n (@b) {$sum = $sum + $n}将所有数组值相加,然后打印结果

答案2

经过几个小时的练习,我提高了我的基本 unix/bash 技能,我发现了一种我认为非常棒的方法。它非常简单,我很惊讶我竟然浪费了这么多时间。下面是代码:

du -s mydir/
for dir in mydir/*/
do
    sudo jpegoptim --strip-all -q "$dir"*.jpg
done
du -s mydir/

就是这样,第一个和第二个输出之间的差异将告诉我节省了多少空间KBdu -s mydir/将告诉我优化之前文件夹的大小,优化之后最终的大小相同。

如果我更擅长使用 bash,我就可以把第一个保存到某个变量中,然后减去第二个。但即使这样对我来说也很好。

相关内容