Awk 如何评估或处理数据中的if语句?

Awk 如何评估或处理数据中的if语句?,awk,gawk,Awk,Gawk,背景 我编写了一个bash脚本,它使用awk从PostgreSQL数据库中提取简单的用户函数,将pgplsql命令转换为SQL(如PERFORM function()到SELECT function(),删除注释--.*,等等),将SQL命令存储到一个文件(file.SQL)并在数据库中读取和执行它们: $ psql ... -f file.sql db 这些函数很简单,主要是调用其他用户定义的函数。但是如何“评估”或处理IF语句呢 IF $1 = 'customer1' THEN

背景

我编写了一个bash脚本,它使用awk从PostgreSQL数据库中提取简单的用户函数,将pgplsql命令转换为SQL(如
PERFORM function()
SELECT function()
,删除注释--.*,等等),将SQL命令存储到一个文件(
file.SQL
)并在数据库中读取和执行它们:

$ psql ... -f file.sql db
这些函数很简单,主要是调用其他用户定义的函数。但是如何“评估”或处理
IF
语句呢

IF $1 = 'customer1' THEN      -- THESE $1 MEANS ARGUMENT TO PGPL/SQL FUNCTION
  PERFORM subfunction1($1);   -- THAT THIS IF STATEMENT IS IN:
ELSE                          -- SELECT function('customer1'); 
  PERFORM subfunction2($1);   -- $1 = 'customer1'
END IF;
Tl;医生:

如果
s等不是SQL,则应使用awk对其进行预评估。可以安全地假设上述内容已处理为一条记录,并删除了注释:

IF $1 = 'customer1' THEN PERFORM subfunction1($1); ELSE PERFORM subfunction2($1); END IF;
在“评估”之后,上述内容应替换为:

SELECT subfunction1('customer1');
如果要对其进行评估的awk被调用:

$ awk -v arg1="customer1' -f program.awk file.sql
或者如果
arg1
是其他内容,例如
customer2

SELECT subfunction2('customer2');
编辑

expr
当我醒来的第一件事突然出现在我的脑海中:

$ awk -v arg="'customer1'" '
{
    gsub(/\$1/,arg)                                     # replace func arg with string
    n=split($0,a,"(IF|THEN|ELSE|ELSE?IF|END IF;)",seps) # seps to get ready for SQL CASE
    if(seps[1]=="IF") {
        # here should be while for ELSEIF
        c="expr " a[2]; c|getline r; close(c)           # use expr to solve 
        switch (r) {                                    # expr has 4 return values
        case "1":                                       # match
            print a[3]
            break
        case "0":                                       # no match
            print a[4]
            break
        default:                                        # (*) see below
            print r
            exit                                        # TODO
}   }   }' file.sql
(*)
expr
输出0,1,2或3:

$ expr 1 = 1
1
$ expr 1 = 2
0
但是,如果省略空格:

$ expr 1=1
1=1

如果您没有编写完整的语言解析器,那么如果您正在寻找便宜且令人愉快的东西,那么这可能是一个不错的起点:

$ cat tst.awk
{ gsub(/\$1/,"\047"arg1"\047") }
match($0,/^IF\s+(\S+)\s+(\S+)\s+(\S+)\s+THEN\s+(\S+)\s+(\S+)\s+ELSE\s+(\S+)\s+(\S+)\s+END\s+IF/,a) {
    lhs = a[1]
    op  = a[2]
    rhs = a[3]
    trueAct  = (a[4] == "PERFORM" ? "SELECT" : a[4]) FS a[5]
    falseAct = (a[6] == "PERFORM" ? "SELECT" : a[6]) FS a[7]

    if (op == "=") {
        print (lhs == rhs ? trueAct : falseAct)
    }
}

$ awk -v arg1='customer1' -f tst.awk file
SELECT subfunction1('customer1');

$ awk -v arg1='bob' -f tst.awk file
SELECT subfunction2('bob');

上面使用GNU awk作为第三个要匹配的参数()。希望很容易理解,您可以根据需要处理其他构造或此构造的其他变体。

这是关于awk的问题,还是关于postgresql的问题?@user31264 awk主要是在postgresql服务器上使用
psql
执行plpgsql脚本之前,将plpgsql脚本预处理为sql。Postgres解决方案也很受欢迎,但我的主要兴趣是awk atm。这是否决投票时的习惯评论。我没有否决投票,但我不明白你在问什么。我觉得您可能需要了解一些SQL或plpgsql或psql或其他方面的知识,以帮助澄清您的需求。如果是,请告知YMMV。你是说你有一个脚本,它的行是
IF$1='customer1',然后执行子功能1($1);否则执行子功能2($1);如果结束是用某种语言编写的,您想编写一个awk脚本来解析这种语言吗?“难道没有什么工具可以做到这一点吗?”@JamesBrown——即使在标记之后,我也不明白。可能是我老了。还没有,我睡着了(:这不是建设性的批评,我在GMT+2)。我会在办公室好好看一看——若我到了那个里,昨晚就下雪了……哦,是的,那个很好。但一定是我的大脑把所有的SSSs都变成了zZzZz。。。