在 awk 程序中重用模式

Ami*_*mit 1 awk

我想编写一个有点长的 awk 程序,从而使我的代码更具可读性且更易于维护。第一个代码片段可以工作,但难以阅读且难以维护。

/\(..-av-es\/.*\)/ {
    split($0, arr, /\(..-av-es\/.*\)/)
}
Run Code Online (Sandbox Code Playgroud)

因此,我想在变量内部定义正则表达式并使用该变量。 $0 ~ PATTERN {...}有效但 split($0, arr, PATTERN)无效。我到底做错了什么?

BEGIN { PATTERN="\(..-av-es\/.*\)"}

$0 ~ PATTERN {
    split($0, arr, PATTERN)

}
Run Code Online (Sandbox Code Playgroud)

编辑:我有一个这样结构的文件。

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
abc (fd-av-es/key1) value1sdfsdaff
jjjjjjjjjjjjjjjjjjjjjjjjjjj
(sd-av-es/key2) value2sdfsdaff 
Run Code Online (Sandbox Code Playgroud)

我的最终目标是拥有一个字符串数组"key1:value1" "key2:value2"

这个片段

/\(..-av-es\/.*\)/ {
    split($0, arr, /\(..-av-es\/.*\)/)
    for ( i in arr) {print NR arr[i]}
}
Run Code Online (Sandbox Code Playgroud)

return 让我更接近 value1 和 value2

2abc
2 value1afjskhslakjhf
4
4 value2jkalshfkjkl
Run Code Online (Sandbox Code Playgroud)

BEGIN { PATTERN="\(..-av-es\/.*\)"}
$0 ~ ES_PATTERN {
    split($0, arr, ES_PATTERN)
    for ( i in arr) {print NR arr[i]}
}
Run Code Online (Sandbox Code Playgroud)

但是返回:

2abc (
2
4(
4
Run Code Online (Sandbox Code Playgroud)

谢谢

Ed *_*ton 5

你的问题是一个正则表达式,所以称它们为正则表达式,而不是高度模糊的“模式”。请参阅如何查找与模式匹配的文本?有关该主题的更多信息。

您不需要提供两次正则表达式,只需执行以下操作:

split($0, arr, /\(..-av-es\/.*\)/) > 1 {
    ...
}
Run Code Online (Sandbox Code Playgroud)

如果出于某种原因您确实想做您想做的事情,那么您应该使用 GNU awk 来执行强类型正则表达式常量:

BEGIN {
    regexp = @/\(..-av-es\/.*\)/
}

$0 ~ regexp {
    split($0, arr, regexp)
    ...
}
Run Code Online (Sandbox Code Playgroud)

或者使用任何其他 awk,您定义一个动态正则表达式,它是一个字符串,然后由 awk 解析两次,首先将其转换为正则表达式,然后将其用作正则表达式,因此您需要加倍转义:

BEGIN {
    regexp = "\\(..-av-es\\/.*\\)"
}

$0 ~ regexp {
    split($0, arr, regexp)
    ...
}
Run Code Online (Sandbox Code Playgroud)

请参阅https://www.gnu.org/software/gawk/manual/gawk.html#Using-Constant-Regexpshttps://www.gnu.org/software/gawk/manual/gawk.html#Compulated-Regexps有关动态正则表达式、常量正则表达式和强类型正则表达式常量之间差异的更多信息。