简体   繁体   English

使用grep + regex从输出中获取特定值,并将其存储在shell中的变量中

[英]Fetch specific value from output using grep+regex and store in variable in shell

First seeking apology for this silly question as i am not expert at all on this. 首先要为这个愚蠢的问题道歉,因为我对此根本不是专家。

I have get the out put from a task like below: 我已经完成了以下任务:

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

From here, i only want to get the value of all 从这里,我只想获取所有的价值

For this i am trying to do this: 为此,我正在尝试这样做:

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

But it does nothing. 但是它什么也没做。

use 采用

"sudo apt-get install imagemagick" 

to make compare workable. 使比较可行。 recommend to use same Image for source and destination, otherwise you will get error for some image mismatch. 建议对源和目标使用相同的图像,否则某些图像不匹配会出现错误。

点击这里

You might need to escape your parenthesis (or just remove them) in: 您可能需要在以下位置转义括号(或仅删除它们):

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

However grep by default will print the whole line, which is not what you want. 但是,默认情况下,grep将打印整行,这不是您想要的。 Printing only the matched text is possible, but extracting the number from that requires a more complex regex which may or may not be available in your version of grep. 仅打印匹配的文本是可能的,但是要从中提取数字,则需要更复杂的正则表达式,这可能在您的grep版本中可用或不可用。 GNU grep has the P flag to enable Perl like regex, and outputting the match only can be done with the o flag. GNU grep具有P标志,可像正则表达式一样启用Perl,仅使用o标志可以输出匹配项。

On the other hand, my recommendation is to use Perl directly: 另一方面,我的建议是直接使用Perl:

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

Note that you also don't need those quotes around $() . 请注意,您也不需要$()周围的引号。 Considering your compare call is working properly and outputting the text in your question, then this should do what you asked: 考虑到您的compare调用正常工作并输出了问题中的文本,那么这应该按照您的要求进行:

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

You can also use variations like /all:\\s*(\\d+)/ if the white space before the number is not guaranteed to be there. 如果不能保证数字前的空格,也可以使用/all:\\s*(\\d+)/类的变体。


The Perl code used here is largely based on the -n flag, which assumes the following loop around the program: 此处使用的Perl代码主要基于-n标志,该标志假定程序周围存在以下循环:

while (<>) {
    # ...
}

This loops iterates over the input line by line, and the <> already assumes input as either stdin or filenames given as arguments. 该循环逐行循环遍历输入,并且<>已经假定输入为标准输入或作为参数指定的文件名。

The -e flag precedes the code itself: -e标志位于代码本身之前:

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

Which is just a shorthand for: 这只是以下内容的简写:

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

Here the match operator m// (or /<regex> for short) tests the default variable $_ to see if there is a match for the regex. 此处,匹配运算符m// (或简称为/<regex> )测试默认变量$_以查看该正则表达式是否匹配。 Who had set the $_ variable? 谁设置了$_变量? The loop itself in its (<>) construct. 循环本身在其(<>)构造中。 It automatically sets $_ to each line being read. 它会自动为每个要读取的行设置$_

If the regex matches, we print it's first set of parenthesis (group), which has its contents set to $1 . 如果正则表达式匹配,我们将打印它的第一组括号(组),其内容设置为$1 If the regex had other groups, they would be stored in $2 , $3 , and so forth. 如果正则表达式具有其他组,则它们将存储在$2$3等中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM