awk筆記linux
1、文本處理工具三劍客nginx
一、grep:文本過濾器,主要功能是指定模式,顯示匹配的文本。正則表達式
二、sed:流編輯器,主要功能是根據指定的模式,來編輯文件。shell
三、awk:報告生成器,主要功能是從文本文件中抽取符合條件的信息,並以特定格式顯示出來。soleries上是nawk,linux上是gawkexpress
2、awk用法與格式編程
awk [options] 'PARTTERN { action }' file1 file2...數組
3、awk的處理機制bash
awk根據定義的parttern一次從文件中依次取出一行文本,對其按指定的分隔符自動切片分開,每個切片是一個位置變量,$0表示一整行文本。less
4、awk的OPTIONStcp
-F:指定切片分隔符
5、awk的PARTTERN
awk 'program' input-file1 input-file2 ...
其中的program爲:
pattern { action }
pattern { action }
...
5.1:常見的模式類型:
一、Regexp:正則表達式,格式爲/regular expression/
案例:
如找到文件中開頭是r的字段:
awk -F: /r/'{print $1}' /etc/passwd
二、expression:表達式,其值非0或爲非空字符時知足條件,如:$1 ~ /foo/ 或$1 == "magedu",用運算符~(匹配)和~!(不匹配)。
案例:
找到文件中$3+1以後大於等於500的UID字段:
awk -F: '$3+1>=500{print $1,$3}' /etc/passwd
找到文件中能被bash匹配到的用戶:
awk -F: '$7 ~ /bash/{print $1,$7}' /etc/passwd
三、Ranges:指定匹配範圍,格式爲pattern1,parttern2,最小匹配單位是一個字段,也就是一個切片。不能用單個字符匹配。
案例:
找到文件中$1是root的,到$1爲halt結尾的中間字段:
awk -F: '$1~"root",$1~"halt"{print $1,$2,$3,$4,$5,$6,$7}' /etc/passwd
錯誤匹配:
awk -F: '/^r/,/h$/{print $1,$2,$3,$4,$5,$6,$7}' /etc/passwd
因爲最小匹配單位是一個切片字段,因此以單個字符匹配是錯誤的。
4.一、BEGIN/END:特殊模式,僅在awk命令執行前運行一次或結束前運行一次
案例:
在輸出的第一行打印一個表頭,輸出最後打印結束信息:
awk -F: 'BEGIN{print "User Bash\n------------------------------------"} {printf "%-20s %-10s\n",$1,$7}END{print "--------------------------------------\nEnd of report"}' /etc/passwd
4.二、若是BEGIN還要加模式的話,那麼模式要寫在BEGIN的後面。好比:
awk -F: 'BEGIN{printf "%-10s%-10s%-10s\n","user_name","user_id","user_bash"}$1~"root",$7~"bash"{printf "%-10s%-10s%-10s\n",$1,$3,$7}END{printf "\n%-10s\n","End Reporting."}' /etc/passwd
五、Empty(空模式):匹配任意輸入行
案例:
沒有任何模式的輸出會對文件的每一行都作處理:
awk -F: '{printf "%-20s%-10s%-20s\n",$1,$3,$7}' /etc/passwd
6、awk的ACTION
一、print:打印指定的文本,多個文本之間用逗號分開,變量不須要加引號,自定義文本須要加引號。
二、printf:可以格式化字符串輸出
printf format item1,item2...
要點:
一、其與print命令的最大不一樣是,printf須要指定format
二、format用於指定後面的每一個item的輸出格式
三、printf語句不會自動打印換行符,\n
format格式的指示符都以%開頭,後跟一個字符,以下:
%c:顯示字符的ASCII碼
%d,%i:十進制整數
%e,%E:科學計數法顯示數值
%f:顯示浮點數
%g,%G:以科學計數法的格式或浮點數的格式顯示數值
%s:顯示字符串
%u:無符號整數
%%:顯示%自身
修飾符:
N:顯示寬度
-:左對齊
+:顯示數值符號
例如:
awk -F: '{printf "%-15s %i\n",$1,$3}' /etc/passwd
三、Expressions(表達式,支持賦值表達式、判斷表達式):
四、Control statements(控制語句,支持if、for、while、case):
4.1
if語句:
語法:{if (condition) {then-body} else {else-body}}
列子1:
找到文件中$1是root的行,若是是root打印admin,不是root打印common user:
awk -F: '{if ($1=="root") printf "%-15s %-10s\n",$1,"is admin user\n";else printf "%-15s %-10s\n",$1,"is common user"}' /etc/passwd
列子2:
統計文件中有多少個用戶的uid大於500。
awk -F: -v sum=0 '{if ($3>500) {sum++}}END{print sum}'
4.2
while循環語句:循環字段的,須要對每個字段都操做的時候才用的到while循環
語法:{while (condition) {statement1;statement2;...}}
列子1:
打印文件中的i<3的列,$1和$2。注意:計算表達式i++要放在action中,每次print完以後執行。
awk -F: '{i=1;while(i<3) {print $i;i++}}' /etc/passwd
列子2:
找到文件中每個字段的字符長度大於等於4的字段。
awk -F: '{i=1;while(i<=NF) {if (length($i)>=4) {print $i};i++}}' /etc/passwd
4.3
do-while語句:和while同樣,只不過do-while把要作的放在前面,條件放在後面。
語法:do {statement1,statement2...} while(condition)
列子1:
打印文件中$i<3的列,$1和$2,注意:計算表達式i++要放在action中,每次print完以後執行。
awk -F: '{i=1;do {print $i;i++} while(i<=3)}' /etc/passwd
4.4
for循環語句:
語法:for(variables assignment; condition; iteration process){statement1,statement2}
列子1:
打印文件中$i<3的列;$1和$2
awk -F: '{for(i=1; i<3; i++) {print $i}}' /etc/passwd
列子2:
打印文件中字符長度大於4的字段
awk -F: '{for(i=1; i<=NF; i++) {if(length($i)>4) {print $i}}}' /etc/passwd
4.4.2
for循環遍歷數組:
語法:for(i in array) {statement1,statement2,...}
列子1:
awk -F: '$NF !~ /^$/{BASH[$NF]++}END{for(A in BASH) {printf "%15s:%i\n",A,BASH[A]}}' /etc/passwd
4.5
case語句:
語法:switch(expression) {case VALUE or /REGEXP/: statement1,statement2, ...default:statement1, ...}
注:case語句的用法學習中沒有找到,等之後有了再補上。
4.6
break和continue
經常使用於循環或case語句中
注:缺乏例子
4.7
next
提早結束對本行文本的處理,並接着處理下一行,例如:下面的命令將顯示其ID號爲奇數的用戶
awk -F: '{if($3%2==0) next;print $1,$3}' /etc/passwd
注意:因爲next的做用,awk在處理if判斷條件爲true的行時,提早結束了,並處理下一行。因此顯示ID號爲奇數的用戶。
五、Compound statements(複合語句):
六、Input statements(輸入語句):
七、Output statements(輸出語句):
八、awk的操做符:
6.8.1:算數操做符:
-x:負值
+x:轉換爲數值
x^y:次方
x*y:乘法
x**y:次方
x/y:除法
x+y:加法
x-y:減法
x%y:取模
6.8.2:字符串操做符
只有一個,並且不用寫出來,用於實現字符串鏈接
6.8.3:賦值操做符
=
+=
-=
*=
/=
%=
^=
**=
++
--
須要注意的是,若是某模式爲=號,此時使用/=/可能會有語法錯誤,應以/[=]/替代
6.8.4:布爾值
awk中,任何非0或非空字符串都爲真,反之就爲假
6.8.5:比較操做符
x < ytrue if x is less than y
x <= ytrue if x is less than or equal to y
x > ytrue if x is greater than y
x >= ytrue if x is greater than or equal to y
x == ytrue if x is equal to y
x != ytrue if x is not equal to y
x ~ ytrue if the string x matches the regexp denoted by y
x !~ ytrue if the string x does not match the regexp denoted by y
subscript in arraytrue if the aray array has an eliment with the subscript subscript
6.8.6:表達式間的邏輯關係符:
&&:邏輯與
||:邏輯或
6.8.7:條件表達式
a=3
b=4
a>b?a is max;b is max
至關於shell的:
if selector;then
if-true-exp
else
if-false-exp
fi
7、AWK中使用數組
9.1
array[index-expression]
index-expression可使用任意字符串:注意,若是某數組元素事先不存在,那麼在引用其時,awk會自動建立此元素並初始化爲空串;所以,要判斷某數組中是否存在某元素,須要使用index in array的方式。
遍歷數組中的每個元素語法:
for (var in array) {statement1, ...}
其中,var用於引用數組下標,而不是元素值:
例子1:
計算當前系統中每一個鏈接狀態的數量
netstat -ant |awk '/^tcp/{state[$NF]++} END{for(a in state) print a,state[a]}'
說明:
一、awk過濾出tcp開頭的全部行並對其操做
二、建立一個state的數組,下標爲ESTABLISHED和LISTEN,++表示找到一個下標,就在原來的基礎上加1。
三、最後END表示,在處理完全部的行,循環數組,a是一個下標,即表明了ESTABLISHED和LISTEN。打印a(下標),和下標的值。
例子2:
計算nginx日誌中每一個IP訪問了多少次
awk '{count[$1]++} END{for(ip in count) {print ip,count[ip]}}' /var/log/nginx/access.log
例子3:
計算nginx日誌中每一個IP訪問每一個資源的次數
awk '{count[$1,$7]++} END{for(ip in count) {printf "%-200s%d\n",ip,count[ip]}}' /var/log/nginx/access_cd.polyguide.com.cn.log
8、awk的內置變量
8.1:和記錄相關的內置變量
一、FS:讀取文本文件時,所使用的字段分隔符,和-F同樣
二、OFS:指定輸出分隔符
三、RS:指定換行符
四、ORS:指定輸出換行符
8.2:和數據相關的內置變量
一、NR:awk命令到目前爲止對全部文件已經處理過了的行數,好比第一個文件處理了100行,第二個文件處理到了21行,那麼NR=121。叫作絕對計數
二、NF:記錄當前行有多少個字段,也就是切片的。
三、FNR:與NR不一樣的是,FNR記錄的是正在處理的文件處理到的行數,無論以前處理過多少文件,FNR是對於當前處理文件的行數。好比第一個文件處理了100行,第二個文件處理到了21行,那麼NR=21。叫作各自計數
四、ARGV:
五、ARGC:
8.3:用戶自定義變量
容許用戶自定義變量,變量名命名規則和大多數編程語言相同,只能使用字母、數字和下劃線,且不能以數字開頭,awk變量名稱區分字符大小寫
變量賦值方法:
一、在awk中賦值
awk 'BEGIN{var="variable testing";print var}'
二、在命令行中賦值
awk -v test="hello awk" 'BEGIN{print test}'
9、awk的內置函數
length([string])
功能:返回string字符串字符的個數
substr(string,start [,length])
功能:取string字符串中的子串,從start開始,取length個:start從1開始計數
system(command)
功能:執行系統command並將結果返回至awk命令
systime()
功能:取系統當前時間
tolower(s)
功能:將s中的全部字母轉爲小寫
toupper(s)
功能:將s中的全部字母轉爲大寫
筆記缺乏:AWK每一個內置函數的列子、自定義函數的用法,包括(定義函數,調用函數,函數傳參)。之後補上,忘大神勿噴。