在 awk 程序中重用模式
Reuse patterns in awk program
我想编写一个有点长的 awk 程序,从而使我的代码更具可读性和更易于维护。第一个代码片段有效,但难以阅读且难以维护。
/\(..-av-es\/.*\)/ {
split([=10=], arr, /\(..-av-es\/.*\)/)
}
因此我想在变量中定义一次正则表达式并使用该变量。
[=17=] ~ PATTERN {...}
有效,但 split([=18=], arr, PATTERN)
无效。我到底做错了什么?
BEGIN { PATTERN="\(..-av-es\/.*\)"}
[=11=] ~ PATTERN {
split([=11=], arr, PATTERN)
}
编辑:
我有一个这样结构的文件。
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
abc (fd-av-es/key1) value1sdfsdaff
jjjjjjjjjjjjjjjjjjjjjjjjjjj
(sd-av-es/key2) value2sdfsdaff
我的最终目标是拥有一个字符串数组 "key1:value1"
"key2:value2"
这个片段
/\(..-av-es\/.*\)/ {
split([=13=], arr, /\(..-av-es\/.*\)/)
for ( i in arr) {print NR arr[i]}
}
returns 这让我更接近 value1 和 value2
2abc
2 value1afjskhslakjhf
4
4 value2jkalshfkjkl
但是
BEGIN { PATTERN="\(..-av-es\/.*\)"}
[=15=] ~ ES_PATTERN {
split([=15=], arr, ES_PATTERN)
for ( i in arr) {print NR arr[i]}
}
然而 returns:
2abc (
2
4(
4
谢谢
你的问题是一个正则表达式,所以称它们为正则表达式,而不是高度模棱两可的“模式”。有关该主题的更多信息,请参阅 。
您不需要提供两次正则表达式,只需这样做:
split([=10=], arr, /\(..-av-es\/.*\)/) > 1 {
...
}
如果出于某种原因你确实想做你想做的事情,那么你应该使用 GNU awk 来实现强类型正则表达式常量:
BEGIN {
regexp = @/\(..-av-es\/.*\)/
}
[=11=] ~ regexp {
split([=11=], arr, regexp)
...
}
或者对于任何其他 awk,您正在定义一个动态正则表达式,它是一个字符串,然后将被 awk 解析两次,首先将其转换为正则表达式,然后将其用作正则表达式,因此您需要加倍转义:
BEGIN {
regexp = "\(..-av-es\/.*\)"
}
[=12=] ~ regexp {
split([=12=], arr, regexp)
...
}
有关动态正则表达式、常量正则表达式和强类型正则表达式常量之间区别的更多信息,请参见https://www.gnu.org/software/gawk/manual/gawk.html#Using-Constant-Regexps and https://www.gnu.org/software/gawk/manual/gawk.html#Computed-Regexps。
我想编写一个有点长的 awk 程序,从而使我的代码更具可读性和更易于维护。第一个代码片段有效,但难以阅读且难以维护。
/\(..-av-es\/.*\)/ {
split([=10=], arr, /\(..-av-es\/.*\)/)
}
因此我想在变量中定义一次正则表达式并使用该变量。
[=17=] ~ PATTERN {...}
有效,但 split([=18=], arr, PATTERN)
无效。我到底做错了什么?
BEGIN { PATTERN="\(..-av-es\/.*\)"}
[=11=] ~ PATTERN {
split([=11=], arr, PATTERN)
}
编辑: 我有一个这样结构的文件。
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
abc (fd-av-es/key1) value1sdfsdaff
jjjjjjjjjjjjjjjjjjjjjjjjjjj
(sd-av-es/key2) value2sdfsdaff
我的最终目标是拥有一个字符串数组 "key1:value1"
"key2:value2"
这个片段
/\(..-av-es\/.*\)/ {
split([=13=], arr, /\(..-av-es\/.*\)/)
for ( i in arr) {print NR arr[i]}
}
returns 这让我更接近 value1 和 value2
2abc
2 value1afjskhslakjhf
4
4 value2jkalshfkjkl
但是
BEGIN { PATTERN="\(..-av-es\/.*\)"}
[=15=] ~ ES_PATTERN {
split([=15=], arr, ES_PATTERN)
for ( i in arr) {print NR arr[i]}
}
然而 returns:
2abc (
2
4(
4
谢谢
你的问题是一个正则表达式,所以称它们为正则表达式,而不是高度模棱两可的“模式”。有关该主题的更多信息,请参阅
您不需要提供两次正则表达式,只需这样做:
split([=10=], arr, /\(..-av-es\/.*\)/) > 1 {
...
}
如果出于某种原因你确实想做你想做的事情,那么你应该使用 GNU awk 来实现强类型正则表达式常量:
BEGIN {
regexp = @/\(..-av-es\/.*\)/
}
[=11=] ~ regexp {
split([=11=], arr, regexp)
...
}
或者对于任何其他 awk,您正在定义一个动态正则表达式,它是一个字符串,然后将被 awk 解析两次,首先将其转换为正则表达式,然后将其用作正则表达式,因此您需要加倍转义:
BEGIN {
regexp = "\(..-av-es\/.*\)"
}
[=12=] ~ regexp {
split([=12=], arr, regexp)
...
}
有关动态正则表达式、常量正则表达式和强类型正则表达式常量之间区别的更多信息,请参见https://www.gnu.org/software/gawk/manual/gawk.html#Using-Constant-Regexps and https://www.gnu.org/software/gawk/manual/gawk.html#Computed-Regexps。