如何从awk调用用户定义的函数?

时间:2017-04-29 20:02:29

标签: bash function awk

我正在尝试连接到数据库并运行查询这是我的脚本

#!/bin/bash
awk '
/----FINAL----/ { f=1 }                     
f=="" || /^--.*--$/ { print; next }   
f { b=b (b==""?"":ORS) $0               
    if(b~/;$/) {                        
        result=dbconnect($b) 
        print result                       #dosomething
        b=""                           
    }
}' sql1.sql

function dbconnect(b)
{
/opt/lampp/bin/mysql -u root myncr <<QUERY_INPUT
$b
QUERY_INPUT

if [ "$?" -eq 0 ];
 then
    return true;
else
    return false;
fi
}

它显示的错误是dbconnect从未定义;我试图在awk中定义函数,但它不起作用。

我的SQL文件如下所示:

---select command------
select * from mytes;
select * from mytest;
select * from mytest;

---insert command------
--INSERT INTO `mytest`(`qlid`, `name`, `email`) VALUES ('nj20302','nancy','nancy@gmail.com');

--update---
UPDATE `mytest` 
SET `name`='james' 
WHERE qlid='jm20322';

----FINAL----
;
select * from mytest;
select * from mytest;

---select command------
---select command------
select * from mytes;
select * from mytest;
select * from mytest;
select * from  mytest;

UPDATE `mytest` 
SET `name`='wendy' 
WHERE qlid='wp50322';

我不想使用system("./dbconnect.sh " $b)

2 个答案:

答案 0 :(得分:1)

我担心melpomene是否正确,你不能从awk程序中调用bash函数(好吧,不管有什么参数改变)。

但是,这是一个显示不同策略的示例程序:

function dbfunction() { 
  echo Processing "'$1'" 
}

awk ' {print $0} ' | while
  read dbcommand  
do
  dbfunction "$dbcommand"
done

所以一般的想法是awk输出的每一行都在下面的while循环中执行。这可以避免系统调用并保持awk程序的性能。你在awk脚本中进行文本处理,然后用bash做你的SQL。

当然,我为你写的循环存在问题。首先,如果一个命令不止一行,事情将无法正常工作(因为读取命令会读到行尾)。

我已经“测试了一下”。以下是您输入的示例运行。请记住,您需要更改输入,以便所有SQL语句出现在一行中:

function dbfunction() { 
  echo Executing "'$1'"
}

awk '
/----FINAL----/ { f=1 }                     
f=="" || /^--.*--$/ {  next }   
f { b=b (b==""?"":ORS) $0               
    if(b~/;$/) {                        
        print b  # do something
        b=""                           
    }
}' sql1.sql | while 
  read sql
do
  dbfunction "$sql"
done

这是执行:

Executing ';'
Executing 'select *from mytest;'
Executing 'select *from'
Executing 'mytest;'
Executing 'select *from mytes;'
Executing 'select *from mytest;'
Executing 'select *from mytest;'
Executing 'select *from'
Executing 'mytest;'
Executing 'UPDATE `mytest` SET `name`='wendy''
Executing 'WHERE qlid='wp50322';'

答案 1 :(得分:0)

也许可以在Awk脚本中完成大部分操作...

#!/usr/bin/awk -f


function db_connect(results, quarry) {
  # ... Runs "quarry" though "mysql -u root myncr"
  #     Saves/appends standard out "results" array
  _results_index = 0
  if (length(results) >= 0) {
    _results_index = length(results)
  }

  cmd = "/opt/lampp/bin/mysql -u root myncr " quarry " 2>/dev/null"
  while (( cmd | getline _results_line ) > 0) {
    results[_results_index] = _results_line
    _results_index++
  }
  close(cmd)
}


BEGIN {
  #... do the parsing of commands from file things
  #    then reset and refill variable for results
          delete quarry_results
          db_connect(quarry_results, $b)
          # ... do something with results maybe
          for {i = 0; i < length(quarry_results); i++} {
            print quarry_results[i]
          }
  # ...
}

以上内容并不完整,但仅作为举例说明,可以使OP的代码在一种脚本语言中最多运行

不确定是否需要将结果 buffer 附加到或在每次通过时重置,因此我在任一选项中都保留了选项。

这种方式的一大缺点是Awk通常不存在标准错误的可能性,尽管在Awk中也可以通过遵循Unix StackExchage -- GNU Awk ERRNO not set on command failure的可用答案之一来实现