一.awk簡介mysql
awk是一種編程語言,用於在linux/unix下對文本和數據進行處理。數據能夠來自標準輸入、一個或多個文件,或其它命令的輸出。它支持用戶自定義函數和動態正則表達式等先進功能,是linux/unix下的一個強大編程工具。它在命令行中使用,但更可能是做爲腳原本使用。linux
awk的處理文本和數據的方式:它逐行掃描文件,從第一行到最後一行,尋找匹配的特定模式的行,並在這些行上進行你想要的操做。若是沒有指定處理動做,則把匹配的行顯示到標準輸出(屏幕),若是沒有指定模式,則全部被操做所指定的行都被處理。
二. awk命令格式和選項
2.1 awk的語法有兩種形式
1. 命令行方式
awk [-F field-separator] 'commands' input-file(s)
其中,commands是真正awk命令,[-F域分隔符]是可選的。input-file(s)是待處理的文件。
在awk中,文件的每一行中,由域分隔符分開的每一項稱爲一個域。一般,在不指名-F域分隔符的狀況下,默認的域分隔符是格。
2. 將全部的awk命令插入一個單獨文件,而後調用:
awk -f awk-script-file input-file(s)
其中,-f選項加載awk-script-file中的awk腳本,input-file(s)跟上面的是同樣的。
2.2 命令選項
1)-F fs or --field-separator fs :指定輸入文件折分隔符,fs是一個字符串或者是一個正則表達式,如-F:。
2)-v var=value or --asign var=value :賦值一個用戶定義變量。
3)-f scripfile or --file scriptfile :從腳本文件中讀取awk命令。
4)-mf nnn and -mr nnn :對nnn值設置內在限制,-mf選項限制分配給nnn的最大塊數目;-mr選項限制記錄的最大數目。這兩個功能是Bell實驗室版awk的擴展功能,在標準awk中不適用。
三. 使用方法
#awk '{pattern + action}' {filenames}
儘管操做可能會很複雜,但語法老是這樣,其中 pattern 表示 AWK 在數據中查找的內容,而 action 是在找到匹配內容時所執行的一系列命令。花括號({ })不須要在程序中始終出現,但它們用於根據特定的模式對一系列指令進行分組。 pattern就是要表示的正則表達式,用斜槓括起來。
awk語言的最基本功能是在文件或者字符串中基於指定規則瀏覽和抽取信息,awk抽取信息後,才能進行其餘文本操做。完整的awk腳本一般用來格式化文本文件中的信息。
一般,awk是以文件的一行爲處理單位的。awk每接收文件的一行,而後執行相應的命令,來處理文本。
四. 模式和操做
4.1. 模式
模式能夠是如下任意一個:
1)正則表達式:使用通配符的擴展集。
2)關係表達式:能夠用下面運算符表中的關係運算符進行操做,能夠是字符
3)串或數字的比較,如$2>$1選擇第二個字段比第一個字段長的行。
4)模式匹配表達式:用運算符~(匹配)和~!(不匹配)。
5)模式,模式:指定一個行的範圍。該語法不能包括BEGIN和END模式。
6)BEGIN:讓用戶指定在第一條輸入記錄被處理以前所發生的動做,一般可在這裏設置全局變量。
7)END:讓用戶在最後一條輸入記錄被讀取以後發生的動做。
五. 記錄和域
5.1. 記錄
awk把每個以換行符結束的行稱爲一個記錄。
記錄分隔符:默認的輸入和輸出的分隔符都是回車,保存在內建變量ORS和RS中。
$0變量:它指的是整條記錄。如$ awk '{print $0}' test將輸出test文件中的全部記錄。
變量NR:一個計數器,每處理完一條記錄,NR的值就增長1。
如$ awk '{print NR,$0}' test將輸出test文件中全部記錄,並在記錄前顯示記錄號。
5.2. 域
記錄中每一個單詞稱作「域」,默認狀況下以空格或tab分隔。awk可跟蹤域的個數,並在內建變量NF中保存該值。如$ awk '{print $1,$3}' test將打印test文件中第一和第三個以空格分開的列(域)。
5.3. 域分隔符
內建變量FS保存輸入域分隔符的值,默認是空格或tab。咱們能夠經過-F命令行選項修改FS的值。如$ awk -F: '{print $1,$5}' test將打印以冒號爲分隔符的第一,第五列的內容。
能夠同時使用多個域分隔符,這時應該把分隔符寫成放到方括號中,如$awk -F'[:/t]' '{print $1,$3}' test,表示以空格、冒號和tab做爲分隔符。
輸出域的分隔符默認是一個空格,保存在OFS中。如$ awk -F: '{print $1,$5}' test,$1和$5間的逗號就是OFS的值。
六. 匹配操做符(~)
用來在記錄或者域內匹配正則表達式。如 awk '$1 ~/^root/' test 將顯示test文件第一列中以root開頭的行。
七. 比較表達式
conditional expression1 ? expression2: expression3,
例如:
$ awk '{max = {$1 > $3} ? $1: $3: print max}' test。若是第一個域大於第三個域,$1就賦值給max,不然$3就賦值給max。
$ awk '$1 + $2 < 100' test。若是第一和第二個域相加小於100,則打印這些行。
$ awk '$1 > 5 && $2 < 10' test,若是第一個域大於5,而且第二個域小於10,則打印這些行。
例子:
若是隻是顯示/etc/passwd的帳戶:
#cat /etc/passwd |awk -F ':' '{print $1}'
root
daemon
bin
sys
若是隻是顯示/etc/passwd的帳戶和帳戶對應的shell,而帳戶與shell之間以tab鍵分割:
#cat /etc/passwd |awk -F ':' '{print $1"+\t"$7}'
root /bin/bash
daemon /bin/sh
bin /bin/sh
sys /bin/sh
若是隻是顯示/etc/passwd的帳戶和帳戶對應的shell,而帳戶與shell之間以逗號分割,並且在全部行添加列名name,shell,在最後一行添加"blue,/bin/nosh":
#cat /etc/passwd |awk -F ':' 'BEGIN {print "name,shell"} {print "$1,$7"} END {print "blue,/bin/nosh"}' name,shell
root,/bin/bash
daemon,/bin/sh
bin,/bin/sh
sys,/bin/sh
....
blue,/bin/nosh
搜索/etc/passwd有root關鍵字的全部行:
#awk -F: '/root/' /etc/passwd
root:x:0:0:root:/root:/bin/bash
這種是pattern的使用示例,匹配了pattern(這裏是root)的行纔會執行action(沒有指定action,默認輸出每行的內容)。
搜索支持正則,例如找root開頭的: awk -F: '/^root/' /etc/passwd正則表達式
其餘小示例:
$ awk '/^(no|so)/' test-----打印全部以模式no或so開頭的行。
$ awk '/^[ns]/{print $1}' test-----若是記錄以n或s開頭,就打印這個記錄。
$ awk '$1 ~/[0-9][0-9]$/(print $1}' test-----若是第一個域以兩個數字結束就打印這個記錄。
$ awk '$1 == 100 || $2 < 50' test-----若是第一個或等於100或者第二個域小於50,則打印該行。
$ awk '$1 != 10' test-----若是第一個域不等於10就打印該行。
$ awk '/test/{print $1 + 10}' test-----若是記錄包含正則表達式test,則第一個域加10並打印出來。
$ awk '{print ($1 > 5 ? "ok "$1: "error"$1)}' test-----若是第一個域大於5則打印問號後面的表達式值,不然打印冒號後面的表達式值。
$ awk '/^root/,/^mysql/' test----打印以正則表達式root開頭的記錄到以正則表達式mysql開頭的記錄範圍內的全部記錄。若是找到一個新的正則表達式root開頭的記錄,則繼續打印直到下一個以正則表達式mysql開頭的記錄爲止,或到文件末尾。sql
FS(字段分隔符)和OFS(輸出的字段分隔符)
FS:字段分隔符
FS默認值爲「 (空格)」,如「hello moto」.
在「hello moto」中有一個空格,空格就是hello與moto的分隔符(separator),而hello與moto就爲字段(files)。awk以空格來區分。
在看看「i----love----you」,若是咱們用命令「awk 「{ print $1 }」」會看到結果爲:
i----love----you
若是想打印出三個字母,經過觀察可發現「----」爲分隔符。
awk 'BEGIN{ FS="----";}{ print $1,$2,$3 }' filename
i love you
OFS:輸出的字段分隔符。
這麼解釋吧,如上例中「i----love----you」,「----」爲分隔符(FS),若是咱們想改成用其餘符號顯示能夠這樣:
awk 'BEGIN{ FS="----";OFS="*****" }{ print $1,$2,$3 }' filename
i*****love*****you
在print的參數之間要用逗號隔開!shell