如何将正则表达式传递给AWK中的函数

时间:2013-09-17 13:56:32

标签: awk

我不知道如何将正则表达式作为参数传递给函数。

如果我传递一个字符串,那就没关系,

我有以下awk文件,

#!/usr/bin/awk -f

function find(name){
    for(i=0;i<NF;i++)if($(i+1)~name)print $(i+1)
}

{
    find("mysql")
}    

我喜欢

$ ./fct.awk <(echo "$str")

这样可以。

但是当我打电话给awk文件时,

{
    find(/mysql/)
}  

这不起作用。

我做错了什么?

谢谢,

Eric J.

4 个答案:

答案 0 :(得分:4)

你不能(不应该)将正则表达式常量传递给用户定义的函数。在这种情况下你必须使用动态正则表达式。比如find("mysql")

如果你find(/mysql/),那么awk做的是:find($0~/mysql/)所以它会将01传递给您的find(..)函数。

详细了解这个问题。

awk variable assignment statement explanation needed

http://www.gnu.org/software/gawk/manual/gawk.html#Using-Constant-Regexps

部分:6.1.2使用正则表达式常量

答案 1 :(得分:3)

warning: regexp constant for parameter #1 yields boolean value

在将正则表达式传递给函数之前,会对正则表达式进行求值(与$0匹配)。你必须使用字符串。

注意:请确保正确转义:http://www.gnu.org/software/gawk/manual/gawk.html#Computed-Regexps

答案 2 :(得分:0)

如果您使用 GNU awk,您可以使用正则表达式作为用户定义的函数参数。
您必须将正则表达式定义为 @/.../

在您的示例中,您可以这样使用它:

function find(regex){
    for(i=1;i<=NF;i++)
            if($i ~ regex)
                    print $i
}

{
    find(@/mysql/)
}    

它名为 strongly type regexp constant,自 GNU awk version 4.2(2017 年 10 月)起可用。

示例 here

答案 3 :(得分:0)

使用引号,将它们视为字符串。这样它适用于 mawk、mawk2 和 gnu-gawk。但您还需要将反斜杠加倍,因为让它们成为字符串会立即吃掉其中一个。

在您的示例中,只需 find("mysql") 就足够了。

您实际上可以按照您的意愿让它通过任意正则表达式,而不仅限于 gnu-gawk,只要您愿意将它们设为字符串而不是其他人提到的 @/../ 语法。这就是反斜杠 # 的不同之处。

你甚至可以用任意字节生成正则表达式,最好是通过八进制代码。如果您将 "\342\234\234" 作为正则表达式,系统会在匹配之前将其转换为正则表达式中的实际字节。

虽然这种方法没有任何意义,但如果您想 100% 安全并且不想让任意字节四处乱飞,请将其写为

"[\\342][\\234][\\234]"  ----> ✜

最初由 awk 读取以创建内部表示后,它将如下所示:

[\342][\234][\234]

仍然会匹配您想要的相同对象(在这种情况下,某种交叉外观的 dingbat)。由于试图将非 ASCII 字节直接括在方括号中,这将在 gawk 的 unicode-aware 模式下发出恼人的警告。对于该用例,

"\\342\\234\\234" ------(eqv to )--->  /\342\234\234/

会让gawk保持快乐和安静。最近,我一直在填补自己代码中的空白,并编写可以模仿 perl 喜欢的所有 Unicode 脚本类的正则表达式。