因为这个我根本不是专家,所以首先为这个愚蠢的问题道歉。
我已经完成了如下任务:
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
从这里,我只想获取 all
的值为此,我正在尝试这样做:
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"
使比较可行。建议对源和目标使用同一张图片,否则某些图片不匹配会出错。
答案 0 :(得分: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
等中。