一個實際應用例子: 在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變量 #^開雙引號 #^關閉雙引號