[英]Fetch specific value from output using grep+regex and store in variable in shell
首先要为这个愚蠢的问题道歉,因为我对此根本不是专家。
我已经完成了以下任务:
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"
使比较可行。 建议对源和目标使用相同的图像,否则某些图像不匹配会出现错误。
您可能需要在以下位置转义括号(或仅删除它们):
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
等中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.