0

首先为这个愚蠢的问题道歉,因为我根本不是这方面的专家。

我从以下任务中得到了输出:

image4.png PNG 1656x839 1656x839+0+0 8-bit sRGB 155KB 0.040u 0:00.039
image4.png PNG 1656x839 1656x839+0+0 8-bit sRGB 155KB 0.020u 0:00.030
Image: image4.png
Channel distortion: AE
red: 0
green: 0
blue: 0
all: 0 
image4.png=>tux_difference.png PNG 1656x839 1656x839+0+0 8-bit sRGB 
137KB 0.500u 0:00.140

从这里,我只想得到所有的价值

为此,我正在尝试这样做:

var="$(compare -verbose -metric ae path/actual.png path/dest.png path/tux_difference.png 2>&1 | grep 'all:\s(\d*)')"

但它什么也没做。

采用

"sudo apt-get install imagemagick" 

使比较可行。建议对源和目标使用相同的图像,否则会因某些图像不匹配而出错。

点击这里

4

1 回答 1

1

您可能需要在以下位置转义括号(或仅删除它们):

grep 'all:\s\(\d*\)'

但是 grep 默认情况下会打印整行,这不是您想要的。仅打印匹配的文本是可能的,但从中提取数字需要更复杂的正则表达式,这在您的 grep 版本中可能可用也可能不可用。GNU grep 具有P启用 Perl 之类的正则表达式的标志,并且只能使用该o标志输出匹配项。

另一方面,我的建议是直接使用 Perl:

perl -ne 'print $1 if /all: (\d+)/'

请注意,您也不需要这些引号$()。考虑到您的compare呼叫正常工作并输出问题中的文本,那么这应该按照您的要求进行:

var=$( compare [...] | perl -ne 'print $1 if /all: (\d+)/' )
echo $var

您还可以使用变体,例如/all:\s*(\d+)/不保证数字前的空格是否存在。


此处使用的 Perl 代码主要基于该-n标志,它假定以下循环围绕程序:

while (<>) {
    # ...
}

此循环逐行迭代输入,并且<>已经假定输入为标准输入或作为参数给出的文件名。

-e标志位于代码本身之前:

print $1 if /all: (\d+)/;

这只是以下的简写:

if (/all: (\d+)/) {
    print $1;
}

在这里,匹配运算符m//(或/<regex>简称)测试默认变量$_以查看是否匹配正则表达式。谁设置了$_变量?循环本身在其(<>)构造中。它会自动设置$_为正在读取的每一行。

如果正则表达式匹配,我们打印它的第一组括号(组),其内容设置为$1. 如果正则表达式有其他组,它们将存储在$2,$3等中。

于 2018-07-04T15:30:29.610 回答