【问题标题】:Why doesn't this simple RegEx work with sed?为什么这个简单的 RegEx 不适用于 sed?
【发布时间】:2013-12-19 22:53:05
【问题描述】:

这是一个非常简单的正则表达式,它不起作用,我不知道为什么。根据this,它应该可以工作。

我使用的是 Mac (OS X 10.8.2)。

script.sh

#!/bin/bash
ZIP="software-1.3-licensetypeone.zip"
VERSION=$(sed 's/software-//g;s/-(licensetypeone|licensetypetwo).zip//g' <<< $ZIP)

echo $VERSION

终端

$ sh script.sh
1.3-licensetypeone.zip

【问题讨论】:

    标签: regex sed


    【解决方案1】:

    sed 适用于简单的正则表达式。您必须使用反斜杠括号和竖线才能使其工作。

    sed 's/software-//g;s/-\(licensetypeone\|licensetypetwo\)\.zip//g'
    

    请注意,我也使用了反斜杠。否则,它会匹配任何字符。

    【讨论】:

    • 复制并粘贴了你的行,但它仍然不适合我。
    • @curtisblackwell: 你的sed 支持; 分隔命令吗?在某些版本中,需要多个-esed -e 's///' -e 's///'
    • 是的,它支持;分隔的多个命令。我正在其他地方使用它。
    • @curtisblackwell:$ZIP 是否包含空格?如果可以,请使用&lt;&lt;&lt; "$ZIP"
    • 不,它没有,但我可能应该使用引号以防它被重命名。
    【解决方案2】:

    可以在shell中做,不需要sed,参数扩展就够了:

    shopt -s extglob
    ZIP="software-1.3-licensetypeone.zip"
    tmp=${ZIP#software-}
    VERSION=${tmp%-licensetype@(one|two).zip}
    

    使用最新版本的 bash(可能未随 OSX 提供)您可以使用正则表达式

    if [[ $ZIP =~ software-([0-9.]+)-licensetype(one|two).zip ]]; then
        VERSION=${BASH_REMATCH[1]}
    fi
    

    或者,如果您只想要连字符分隔的字符串中的第二个单词

    VERSION=$(IFS=-; set -- $ZIP; echo $2)
    

    【讨论】:

    • 您的最后一个建议解决了我的问题。谢谢!但是,我仍然不明白为什么 RegEx 不起作用。
    • choroba 在他的回答中解释了这一点。不同的程序(perl、sed、bash 等)以不同的方式实现正则表达式。使用 sed,您需要对括号进行转义以赋予它们特殊的含义。
    • 听起来不错,但即使我逃脱了他们,也没有用。我的 sed 版本是否可能不支持正则表达式中的括号和/或管道?
    • 极不可能。你也逃过管道吗?非常仔细地阅读 choroba 的答案。您还需要查看 man sed 和(可能)man ed 以了解 sed 实现的正则表达式。
    • 我仔细阅读了他的回答。重读了很多遍,因为我认为它是正确的。但是,即使复制和粘贴 RegEx 也不起作用。我将再次检查 man sed,并查看 ed。谢谢。
    【解决方案3】:

    查看 OS X 10.7.4 的 regex documentation(但应该适用于 OP 的 10.8.2),在最后一段中提到

    过时的(基本)正则表达式在几个方面有所不同。 | 是一个普通字符,它的功能没有等价物......

    ...嵌套子表达式的括号是\(' and )'...

    sed,不带任何选项,使用基本正则表达式 (BRE)。

    要在 OS X 或 BSD 的 sed 中使用 |,您需要通过 -E 选项启用扩展正则表达式 (ERE),即

    sed -E 's/software-//g;s/-(licensetypeone|licensetypetwo).zip//g'
    

    p/s:BRE 中的\| 是一个 GNU 扩展。


    提取版本号的替代方法

    1. chop-chop(参数扩展)

      VERSION=${ZIP#software-}
      VERSION=${VERSION%-license*.zip}
      
    2. sed

      VERSION=$(sed 's/software-\(.*\)-license.*/\1/' <<< "$ZIP")
      

      您不一定要使用 shell 模式或正则表达式逐字匹配字符串。

    【讨论】:

      【解决方案4】:
      $ man sed | grep "regexp-extended" -A2
             -r, --regexp-extended
      
                    use extended regular expressions in the script.
      

      【讨论】:

        猜你喜欢
        • 2017-09-07
        • 2021-09-03
        • 1970-01-01
        • 2020-09-25
        • 2022-01-10
        • 2019-06-04
        • 2016-02-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多