如何使用正则表达式提取 Bash 中的部分字符串

How to extract part of string in Bash using regex

我一直在尝试提取 bash 中的部分字符串。我在 Mac.

上使用它

输入字符串的模式:

示例输入和输出:

abc/def-1234-random-words // def-1234
bla/foo-12-random-words // foo-12
bar-12345-random-words // bar-12345

所以我尝试按照命令来获取它,但由于某些奇怪的原因,它 returns 整个字符串。

extractedValue=`getInputString | sed -e 's/.*\(\(def\|bar\|foo\)-[^-]*\).*//g'`
// and
extractedValue=`getInputString | sed -e 's/.*\(\(def\|bar\|foo\)-\d{2,6}\).*//g'`

我还尝试使用 I 标志使其不区分大小写,但它为我抛出了错误:

: bad flag in substitute command: 'I'


以下是我试过的参考资料:

这个 gnu sed 应该与忽略大小写标志一起使用:

sed -E 's~^(.*/){0,1}((def|foo|bar)-[0-9]{2,6})-.*~~I' file

def-1234
foo-12
bar-12345

这个 sed 匹配:

  • (.*/){0,1}: 匹配一个字符串最多 / 可选地在开头
  • (: 开始捕获组 #2
    • (def|foo|bar):匹配deffoobar
    • -:匹配一个-
    • [0-9]{2,6}:匹配2到6位数字
  • ): 结束捕获组#2
  • -.*:匹配 - 后跟任何内容直到结束
  • 替换是我们在第 2 组中捕获的值

或者你可以使用这个 awk:

awk -v IGNORECASE=1 -F / 'match($NF, /^(def|foo|bar)-[0-9]{2,6}-/) {print substr($NF, 1, RLENGTH-1)}' file

def-1234
foo-12
bar-12345

awk解释:

  • -v IGNORECASE=1: 启用忽略大小写匹配
  • -F /:使用/作为字段分隔符
  • match($NF, /^(def|foo|bar)-[0-9]{2,6}-/):在 $NF 中使用正则表达式 ^(def|foo|bar)-[0-9]{2,6}- 匹配文本,这是使用 / 作为字段分隔符的最后一个字段(忽略 / 之前的文本)
  • 如果匹配成功则使用 substr 打印从位置 1RLENGTH-1 的文本(因为我们匹配到 - 之后的数字)

可以使用-E选项来使用扩展正则表达式,那么就不用转义(|.

echo abc/def-1234-random-words  | sed -E -e 's/.*((def|bar|foo)-[^-]*).*//g'
def-1234