2

我有一个包含文本的变量;我可以将它回显到标准输出,所以我认为这个变量很好。我的问题是尝试在该文本变量中查找模式。这是我正在尝试的:

ERR_COUNT=`echo $VAR_WITH_TEXT | grep "ERROR total: (\d+)"`

当我回显 $ERR_COUNT 时,变量似乎为空,所以我一定做错了什么。

如何正确执行此操作?谢谢。

编辑-只是想提一下,在变量中的示例文本上测试该模式确实给了我一些东西(我测试过:http ://rubular.com )

然而,正则表达式仍然可能是错误的。

EDIT2 - 还没有得到任何结果,所以这是我正在使用的字符串:

ALERT line125: Alert: Cannot locate any description for 'asdf' in the qwer.xml hierarchy. (due to (?i-xsm:\balert?\b) ALERT in ../hgfd.controls) ALERT line126: Alert: Cannot locate any description for 'zxcv' in the qwer.xml hierarchy. (due to (?i-xsm:\balert?\b) ALERT in ../dfhg.controls) ALERT line127: Alert: Cannot locate any description for 'rtyu' in the qwer.xml hierarchy. (due to (?i-xsm:\balert?\b) ALERT in ../kjgh.controls) [1] 22280 IGNORE total: 0 WARN total: 0 ALERT total: 3 ERROR total: 23 [1] + Done /tool/pandora/bin/gvim -u NONE -U NONE -nRN -c runtime! plugin/**/*.vim -bg ...

那是字符串,所以希望不再有歧义......我想将数字“23”(在“ERROR total:”之后)提取到一个变量中,我很难过哈哈。

干杯

4

4 回答 4

6

您可以使用 bash 的=~运算符来提取值。

[[ $VAR_WITH_TEXT =~ ERROR\ total:\ ([0-9]+) ]]

请注意,您必须转义空格,或者只引用正则表达式的固定部分:

[[ $VAR_WITH_TEXT =~ "ERROR total: "([0-9]+) ]]

因为引用任何元字符会导致它们被逐字处理。

您还可以将正则表达式保存在变量中:

regex="ERROR total: ([0-9]+)"
[[ $VAR_WITH_TEXT =~ $regex ]]

无论如何,一旦表达式匹配,括号中的表达式可以在BASH_REMATCH数组中找到。

ERR_COUNT=${BASH_REMATCH[1]}

(第零个元素包含整个匹配的正则表达式;括号中的子表达式按照它们在完整正则表达式中出现的顺序在其余元素中找到。)


如果你想使用grep,你需要一个可以接受 Perl 风格正则表达式的版本。

ERR_COUNT=$( echo "$VAR_WITH_TEXT" | grep -Po "(?<=ERROR total: )\d+" )

只要你需要使用 Perl 风格的正则表达式来启用后向断言,你可以[0-9]\d.

于 2012-08-07T02:49:11.473 回答
3

您的错误在模式中:(\d+)匹配:

  • '('
  • 一个数字
  • '+'
  • ')'

根据您的评论,您想要的是\(\d\+\)

  • 定义一个子模式\( ... \)
    • 里面至少匹配一个 ( \+) 数字 ( \d)。

在这种情况下,如果您不需要子模式,您可以删除\(and \)

注意:如果您grep不明白\d,可以将其替换为[0-9]。最简单的方法是grep '\d'通过编写几行测试来编写和测试它。

于 2012-08-06T22:30:57.523 回答
2
# setting example data
    test="adfa\nfasetrfaqwe\ndsfa ERROR total: 32514235dsfaewrf"

一种解决方案:

echo $(sed -n 's/^.*ERROR total: \([0-9]*\).*$/\1/p' < <(echo $test))
32514235

其他解决方案:

# throw away everything up to "ERROR total: "
test=${test##*ERROR total: } 
# cut from behind assuming number contains no spaces and is
# separated by space
test=${test%% *}
echo $test
32514235
于 2012-08-06T22:27:13.647 回答
1

可能仅在 perl 正则表达式模式下\d被识别为数字,您可能想要使用grep -P.

如果您只想要您可以尝试的号码:

ERR_COUNT=$(echo $VAR_WITH_TEXT | perl -pe "s/.*ERROR total: (\d+).*/\1/g")

或者:

ERR_COUNT=$(echo $VAR_WITH_TEXT | sed -n "s/.*ERROR total: ([0-9]+).*/\1/gp")

于 2012-08-06T22:30:02.577 回答