如何在/ bin / sh脚本中使用正则表达式获取字符串的一部分

时间:2014-05-08 15:34:46

标签: regex shell sed

我需要在shell脚本中提取字符串的一部分。原始字符串非常复杂,所以我真的需要一个正则表达式来选择原始字符串的正确部分 - 只是删除前缀和后缀将不起作用。此外,正则表达式需要检查我想要提取的字符串的上下文,所以我例如需要使用正则表达式a\([^b]*\)b123中提取12a123b23

shell脚本需要是可移植的,因此我无法使用Bash结构[[BASH_REMATCH

我希望脚本是健壮的,所以当正则表达式不匹配时,脚本应该注意到这一点,例如通过要使用的命令的非零退出代码。

这样做的好方法是什么?


我尝试了各种工具,但没有一个能完全解决问题:

  • expr match "$original" ".*$regex.*"除错误情况外有效。使用此命令,我不知道如何检测正则表达式是否不匹配。此外,expr似乎采取提取的字符串来确定其退出代码 - 所以当我碰巧提取00时,expr的退出代码为1.所以我需要通常忽略退出代码{{1} }

  • 除了错误情况,
  • expr match "$original" ".*$regex.*" || true也有效。为了处理这种情况,我需要测试我是否找回原来的字符串,这也非常不优雅。

那么,有没有更好的方法呢?

3 个答案:

答案 0 :(得分:3)

您可以使用-n的{​​{1}}选项来抑制所有输入行的输出,并将sed选项添加到substitute命令中,如下所示:

p

如果正则表达式匹配,则匹配的组将像以前一样打印。但是现在如果正则表达式不匹配,则不会打印任何内容,您只需要测试空字符串。

答案 1 :(得分:2)

grep -o唯一可能的问题是可移植性,否则它满足所有要求:

➜  echo "hello and other things" | grep -o hello
hello
➜  echo $?
0
➜  echo "hello and other things" | grep -o nothello
➜  echo $?
1

最好的事情之一是,因为它是grep你可以选择你想要的正则表达式,无论是BRE,ERE还是Perl。

答案 2 :(得分:0)

如果egrep可用(几乎所有时间)

egrep 'YourPattern' YourFile

egrep "${YourPattern}" YourFile

如果只有grep可用

grep -e 'YourPattern' YourFile

您使用经典[ $? -eq 0 ]检查命令的状态(还考虑了错误的YourFile访问权限)

对于内容本身,用sed或awk提取(用于可移植性问题)(在失败测试之后)

Content="$( sed -n -e "s/.*\(${YourPattern}\).*/\1/p;q" )"