如何将正则表达式与 Awk 一起使用来提取括号之间的子字符串



在下面的 Bash 命令行中,当子字符串在双引号之间时,我能够获取子字符串的索引。

text='123ABCabc((XYZabc((((((abc123(((123'
echo $text | awk '{ print index($0, "((((a" )}'  # 20 is the result.

但是,在我的应用程序中,我不会知道此示例中"a"的位置是什么字符。因此,我想我可以用一个正则表达式替换"a",该正则表达式接受除"("以外的任何字符。我认为/[^(}/将是我需要的。但是,我一直无法让 Awk index 命令与任何形式的正则表达式一起使用,以代替示例中的"((((a。

更新:William Pursell 指出,索引操作不接受正则表达式作为第二个操作数。

最终,我试图完成的是提取位于四个或更多"(",后跟一个或多个")"之后的子字符串。 Dennis Williamson 为解决方案提供了以下代码:

echo 'dksjfkdj(((((((I-WANT-THIS-SUBSTRING)askdjflsdjf' | 
mawk '{match($0,/(((([^()]*)/); s = substr($0,RSTART, RLENGTH); gsub(/[()]/, "", s); print s}'

感谢大家的帮助!

如果要

匹配四个或更多左括号以查找匹配中另一个子字符串的开头,则实际上必须计算值。

# Use GNU AWK to index the character after the end of a substring.
echo "$text" |
awk --re-interval 'match( $0, /({4,}/ ) { print RSTART + RLENGTH }'

这应该在括号序列之后为您提供字符的正确起始索引,在本例中为 24。

要获取第一个非开括号在一系列非开括号之后的位置:

$ echo "$text" | awk '{ print match($0, /((((([^(])/, arr); print arr[1, "start"]}'
20
24

这显示了子字符串"((([^(]"(20))的位置以及括号(24)后面的字符位置。

match()做到这一点的能力是一个GNU(gawk)扩展。

编辑:

echo 'dksjfkdj(((((((I-WANT-THIS-SUBSTRING)askdjflsdjf' | 
    mawk '{match($0,/(((([^()]*)/); s = substr($0,RSTART, RLENGTH); gsub(/[()]/, "", s); print s}'

你想要match而不是索引。 你需要逃离(。 例如:

echo $text | awk '{ print match($0, /(((([^(]/) }'

注意,这不会给出字符串 (((( 后面的字符索引,而是给出第一个(的索引。

最新更新