“贪婪”搜索并替换 sed

art*_*ton 3 bash sed

我有一个 bash 函数,可以从字符串中获取前缀,直到并包括字符“-”。

get_prefix_with_hyphen() {
  # get prefix with trailing hyphen
  prefix_with_hyphen=$(echo "$1" | sed 's/-.*$/-/')
  if [ "$prefix_with_hyphen" = "$1" ]; then
    echo ""
  else
    echo "$prefix_with_hyphen"
  fi
}
Run Code Online (Sandbox Code Playgroud)

这对于“”、“字符串”和“a-字符串”非常有效:

echo $(get_prefix_with_hyphen "")

echo $(get_prefix_with_hyphen "string")

echo $(get_prefix_with_hyphen "a-string")
a-
Run Code Online (Sandbox Code Playgroud)

但如果字符串中有两个或多个连字符,它将返回第一个连字符之前的所有内容(包括第一个连字符)。我希望它包含最后一个连字符之前的所有内容:

echo $(get_prefix_with_hyphen "a-long-string")
a-
# would like to return "a-long-"
Run Code Online (Sandbox Code Playgroud)

如何在 sed 或其他工具中实现“贪婪”模式匹配?

函数中还有一个附加的“if”语句。是否可以删除它并以某种方式使用不同的正则表达式来实现相同的结果?

mar*_*rkp 5

使用参数替换的替代方法

get_prefix_with_hyphen() { 
    prefix_with_hyphen="${1%-*}"                  # parameter substitution; NOTE: removes trailing '-'
    if [ "$prefix_with_hyphen" = "$1" ]; then
       echo ""
    else 
       prefix_with_hyphen+="-"                    # make sure to append trailing '-'
       echo "${prefix_with_hyphen}"
    fi
}
Run Code Online (Sandbox Code Playgroud)

注意:这具有消除当前生成两个子 shell 的性能开销的额外好处 ( echo | sed)

进行试驾:

$ get_prefix_with_hyphen ""

$ get_prefix_with_hyphen "string"

$ get_prefix_with_hyphen "a-string"
a-
$ get_prefix_with_hyphen "a-long-string"
a-long-
Run Code Online (Sandbox Code Playgroud)