如何使用awk的正则表达式提取括号之间的子串?

时间:2012-05-31 15:38:41

标签: regex indexing awk substring

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

text='123ABCabc((XYZabc((((((abc123(((123'

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

但是,在我的应用程序中,我不知道在这个例子中“a”的字符是什么。因此,我认为我可以用接受“(”之外的任何字符的正则表达式替换“a”。我认为/ [^(} /将是我需要的。但是,我无法获得Awk索引命令使用任何形式的正则表达式代替“((((示例中的”a“。

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

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

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

感谢所有人的帮助!

3 个答案:

答案 0 :(得分:3)

在一系列序列之后得到第一个非开括号的位置:

$ 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}'

答案 1 :(得分:1)

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

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

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

答案 2 :(得分:1)

如果要匹配四个或更多个空心圆括号以便找到匹配中另一个子字符串的开头,则实际上必须计算该值。

# 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。