Bash 正则表达式字符串变量匹配

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37935415/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 14:48:13  来源:igfitidea点击:

Bash regex string variable match

regexbashperl

提问by The Georgia

I have the following script i wrote in perl that works just fine. But i am trying to achieve the same thing using bash.

我有以下用 perl 编写的脚本,效果很好。但我正在尝试使用 bash 来实现同样的目的。

    #!/usr/bin/perl

use 5.010;
use strict;

INIT {
    my $string = 'Seconds_Behind_Master: 1';
    my ($s) = ($string =~ /Seconds_Behind_Master: ([\d]+)/);
    if ($s > 10) {
        print "Too long... ${s}";
    } else {
        print "It's ok";
    }
}

__END__

How can i achieve this using a bash script? Basically, i want to be able to read and match the value at the end of the string "Seconds_Behind_Master: N" where N can be any value.

我如何使用 bash 脚本实现这一目标?基本上,我希望能够读取和匹配字符串“Seconds_Behind_Master: N”末尾的值,其中 N 可以是任何值。

回答by Krzysztof Krasoń

You can use a tool for it e.g. sedif you want to stay with regexps:

你可以使用一个工具,例如,sed如果你想继续使用正则表达式:

#!/bin/sh
string="Seconds_Behind_Master: 1"
s=`echo $string | sed -r 's/Seconds_Behind_Master: ([0-9]+)//g'`
if [ $s -gt 10 ]
then
    echo "Too long... $s"
else
    echo "It's OK"
fi

回答by xxfelixxx

You can use regular expression in bash, just like in perl.

您可以在 bash 中使用正则表达式,就像在 perl 中一样。

#!/bin/bash

STRING="Seconds_Behind_Master: "

REGEX="Seconds_Behind_Master: ([0-9]+)"

RANGE=$( seq 8 12 )

for i in $RANGE; do
    NEW_STRING="${STRING}${i}"
    echo $NEW_STRING;

    [[ $NEW_STRING =~ $REGEX ]]
    SECONDS="${BASH_REMATCH[1]}"
    if [ -n "$SECONDS" ]; then
        if [[ "$SECONDS" -gt 10 ]]; then
            echo "Too Long...$SECONDS"
        else
            echo "OK"
        fi
    else
        echo "ERROR: Failed to match '$NEW_STRING' with REGEX '$REGEX'"
    fi
done

Output

输出

Seconds_Behind_Master: 8
OK
Seconds_Behind_Master: 9
OK
Seconds_Behind_Master: 10
OK
Seconds_Behind_Master: 11
Too Long...11
Seconds_Behind_Master: 12
Too Long...12

man bash #BASH_REMATCH

男人 bash #BASH_REMATCH

回答by tripleee

The specific case of "more than a single digit" is particularly easy with just a pattern match:

“多于一位数”的特定情况仅通过模式匹配就特别容易:

case $string in
   *Seconds_Behind_Master: [1-9][0-9]*) echo Too long;;
   *) echo OK;;
esac

To emulate what your Perl code is doing more closely, you can extract the number with simple string substitutions.

要更接近地模拟 Perl 代码的作用,您可以使用简单的字符串替换来提取数字。

s=${string##*Seconds_Behind_Master: }
s=${s%%[!0-9]*}
[ $s -gt 10 ] && echo "Too long: $s" || echo OK.

These are glob patterns, not regular expressions; *matches any string, [!0-9]matches a single character which is not a digit. All of this is Bourne-compatible, i.e. not strictly Bash only (you can use /bin/shinstead of /bin/bash).

这些是 glob 模式,而不是正则表达式;*匹配任何字符串,[!0-9]匹配不是数字的单个字符。所有这些都是与 Bourne 兼容的,即严格来说不仅仅是 Bash(您可以使用/bin/sh代替/bin/bash)。