5

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

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

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

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

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

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

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

感谢大家的帮助!

4

3 回答 3

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}'
于 2012-05-31T16:14:56.343 回答
2

如果你想匹配四个或更多的左括号以在匹配中找到另一个子字符串的开始,你实际上必须计算该值。

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

于 2012-05-31T16:09:14.190 回答
1

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

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

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

于 2012-05-31T15:45:12.137 回答