在awk中通过system调用sql语句来说明引号的使用

一个实际应用例子: 在awk中,通过system调用连接数据库并作select操作,select语句中where条件来自于一个文件(file)的第一个域($1)。

$ cat file
 ...
 1001
 1002
 1003
 1004
 ...

1. 用awk实现:

awk {system("mysql -u root -proot mydatabase -Bse \"select id,name from tables where id=""\047"$1"\047""\042")} file

为什么类似上面的语句可以达到目的呢?首先,我们来将这个语句进行详细分解,因为有这么多引号和转义符,看起来确实很让人头大。直接看system语句的内容(说明:为了看得更清楚,将由双引号分隔的子字符串以空格和回车符分开。):

"mysql -u root -proot mydatabase -Bse \"select id,name from tables where id="
 "\047"
 $1
 "\047"
 "\042"

解释:\047和\042分别为单引号和双引号的转义符号(可以在shell终端通过echo -ne “\047″和echo -ne “\042″输出看它们代表的字符),相匹配的引号以相同的颜色进行标记。\”  与  \042 配对,\047 与 \047 配对,然后将这5个部分拼接起来就构成一个完整的语句。

2. 该语句也可以写成:

awk {system("mysql -u root -proot mydatabase -Bse \"select id,name from tables where id=\‘‘"$1"‘\‘\"")} file

引号分解:

awk {system( "...id=       \            "  $1  "        \‘         \"     "   )} file

    #^最外层的引号(无论是单引号或双引号),是shell解释的,shell将引号内的内容当成一个不可拆分的整体,去掉最外层引号后传给awk,多双引号连在一起,中间无空格,仍作为1个位置参数传给awk

                      #^关了单引号,好让\传给awk一个转义的

                                     #^开单引号

                                            #^关了双引号,好引用$1

                                                   #^awk system参数的前双引号

                                                        #^shell的外层后单引号,目的是要传一个转义单引号给awk

                                                              #^shell转义单引号给awk,前后不能空,空了awk程序就断开了

                                                                    #^shell解释的外层前单引号,前面不能空

                                                                          #^传给子进程shell的双引号,前后可空

                                                                                #^awk后双引号,前面可空

3. 将sql语句的结果存储为一个awk变量

export dbfile=./freepbx.db   # 定义shell变量,freepbx.db为freepbx的sqlite3数据库文件
echo | awk {var=1000;("sqlite3 $dbfile \"select name,sipname from users where extension="var"\"") | getline data;print data }
#引号分解:
echo | awk {var=1000;("sqlite3 $dbfile \"select ... extension="var" \" ") | getline data;print data }

           #^最外层,由shell解释

                       #^调用shell执行括号内的命令,去掉括号会报错:/bin/sh: -c: 行 0: 寻找匹配的 `"‘ 是遇到了未预期的文件结束符;/bin/sh: -c: 行 1: 语法错误: 未预期的文件结尾

                                #^关闭单引号,传递shell变量

                                       #^打开单引号

                                                                  #^关闭双引号,传递awk变量

                                                                     #^开双引号

                                                                            #^关闭双引号

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。