一个实际应用例子: 在awk中,经过system调用链接数据库并做select操做,select语句中where条件来自于一个文件(file)的第一个域($1)。mysql
$ cat file ... 1001 1002 1003 1004 ...
1. 用awk实现:sql
awk '{system("mysql -u root -proot mydatabase -Bse \"select id,name from tables where id=""\047"$1"\047""\042")}' file
为何相似上面的语句能够达到目的呢?首先,咱们来将这个语句进行详细分解,由于有这么多引号和转义符,看起来确实很让人头大。直接看system语句的内容(说明:为了看得更清楚,将由双引号分隔的子字符串以空格和回车符分开。):shell
"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. 该语句也能够写成:spa
awk '{system("mysql -u root -proot mydatabase -Bse \"select id,name from tables where id='\''"$1"'\''\"")}' file
引号分解:code
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变量sqlite
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变量 #^开双引号 #^关闭双引号