【问题标题】:Bash regex string variable matchBash 正则表达式字符串变量匹配
【发布时间】:2016-10-22 11:17:04
【问题描述】:

我有以下我用 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__

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

【问题讨论】:

  • INIT 块中运行代码似乎令人困惑和分心。如果它是您要翻译的块的内容,只需将其削减。另见minimal reproducible example
  • tripleee,我想在 bash 中实现逻辑,因此在 perl 脚本中使用 init 并不那么重要。所以是的,请只关注内部代码内容。

标签: regex bash perl


【解决方案1】:

你可以在 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

输出

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 嗯? Bash 具有基于 glob 的字符串替换,非常有能力解决这个问题。
    • 这个问题是关于正则表达式的,我认为 bash 没有,但从其他回复中我可以看出它确实有。至于 glob - 这些不是问题标题中要求的正则表达式。
    【解决方案3】:

    “多于一个数字”的具体情况特别简单,只需一个模式匹配:

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

    为了更接近地模拟您的 Perl 代码所做的事情,您可以通过简单的字符串替换来提取数字。

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-14
      • 1970-01-01
      • 2012-06-05
      • 2013-12-25
      • 1970-01-01
      相关资源
      最近更新 更多