awk經常使用內置變量:
FS: field separator(輸入字段分隔符),默認是空白字符
OFS:output field separator,輸出字段分隔符
NF:Number of Field,當前記錄的field個數
RS: Record separator(記錄分隔符),默認是換行符
NR: The number of input records,awk命令所處理的記錄數;若是有多個文件,這個數目會把處理的多個文件中行統一計數
FNR: 與NR不一樣的是,FNR用於記錄正處理的行是當前這一文件中被總共處理的行數
awk命令的使用格式:
# awk [options] 'script' file1,file2,...
# awk [options] 'PATTERN { action }' file1,file2,...
根據指定的分隔符將讀入的文本切片,默認分隔符爲空格,引用第一段$1,引用第二段$2,...引用所有字段$0
用法示例:
[root@rs1 test]# awk '{print $1}' a.txt
[root@rs1 test]# df -hP | awk '{print $1}'
awk中字段分隔符的指定方式:
一、[root@rs1 ~]# awk -F : '{print $1}' /etc/passwd 指定以」:「爲分隔符
二、[root@rs1 test]# awk -v FS=: '{print $NF}' /etc/passwd指定以」:「爲分隔符 -v表示聲明一個變量
三、[root@rs1 ~]# awk 'BEGIN{FS=":"}{print $1,$3}' /etc/passwd在命令執行以前爲變量賦值
四、[root@rs1 test]# awk -v OFS=: '{print $1,$2}' a.txt OFS 指定輸出字段分隔符
1、print子命令的用法
print的使用格式:
print item1, item2, ...
要點:
一、各項目之間使用逗號隔開,而輸出時則以空白字符分隔
二、輸出的item能夠爲字符串或數值、當前記錄的字段(如$1)、變量或awk的表達式;數值會先轉換爲字符串,然後再輸出
三、print命令後面的item能夠省略,此時其功能至關於print $0, 所以,若是想輸出空白行,則須要使用print ""
用法示例:
# awk 'BEGIN { print "line one\nline two\nline three" }'
# awk -F: '{ print $1, $2 }' /etc/passwd
2、printf
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
[root@rs1 test]# awk '{printf "%-10s%s\n",$1,$2}' a.txt
3、輸出重定向
print items > output-file 保存到某文件中
print items >> output-file 追加到某文件中
print items | command 使用管道交給某些命令處理
特殊文件描述符:
/dev/stdin:標準輸入
/dev/sdtout: 標準輸出
/dev/stderr: 錯誤輸出
/dev/fd/N: 某特定文件描述符,如/dev/stdin就至關於/dev/fd/0
用法示例:
# awk -F: '{printf "%-15s %i\n",$1,$3 > "/dev/stderr" }' /etc/passwd
awk中常見的模式類型:
一、Regexp: 正則表達式,格式爲/regular expression/
二、expresssion:表達式,其值非0或爲非空字符時知足條件,如:$1 ~ /foo/ 或 $1 == "magedu",用運算符~(匹配)和~!(不匹配)
三、Ranges: 指定的匹配範圍,格式爲pat1,pat2 /bash/,/awk/從被/bash/匹配到的行開始到被/awk/匹配到的行結束
四、BEGIN/END:特殊模式,僅在awk命令執行前運行一次或結束前運行一次
五、Empty(空模式):匹配任意輸入行
用法示例:
[root@rs1 test]# awk 'BEGIN{print "a" "b"}'字符串操做符,將兩個字符串直接鏈接
[root@rs1 test]# awk -F: '$1 ~ /^root/ {print $3,$4,$NF}' /etc/passwd 顯示被模式匹配到的行的第三第四和最有一個字段
[root@rs1 test]# awk -F: '$1 !~ /^root/ {print $3,$4,$NF}' /etc/passwd不能被模式匹配
[root@rs1 test]# awk -F: '/bash/{print $0}' /etc/passwd
[root@rs1 test]# awk -F: '$3>=500{print $1,$3}' /etc/passwd
[root@rs1 ~]# awk -F: 'BEGIN{print "Username UID"}{printf "%-15s%s\n",$1,$3}END{print "Over"}' /etc/passwd
awk中的控制語句:
一、if-else
語法:if (condition) {then-body} else {[ else-body ]}
例子:
awk -F: '{if ($1=="root") print $1, "Admin"; else print $1, "Common User"}' /etc/passwd
awk -F: '{if ($1=="root") printf "%-15s: %s\n", $1,"Admin"; else printf "%-15s: %s\n", $1, "Common User"}' /etc/passwd
awk -F: -v sum=0 '{if ($3>=500) sum++}END{print sum}' /etc/passwd
二、while
語法: while (condition){statement1; statment2; ...}
[root@rs1 ~]# awk -F: '$1!~/root/{i=1;while (i<=4) {print $i;i++}}' /etc/passwd
[root@rs1 ~]# awk -F: '$1!~/root/{i=1;while (i<=NF) {print $i;i+=2}}' /etc/passwd只顯示奇數字段
三、do-while
語法: do {statement1, statement2, ...} while (condition)
四、for
語法: for ( variable assignment; condition; iteration process) { statement1, statement2, ...}
for循環還能夠用來遍歷數組元素:
語法: for (i in array) {statement1, statement2, ...}
遍歷數組中的每個元素
for {A in ARRAY} {print ARRAY[A]}
A中保存數組下標
[root@rs1 ~]# awk 'BEGIN{A["m"]="hello";A["n"]="world";for (B in A) print A[B]}' B中保留數組A的下標
[root@rs1 ~]# awk -F: '{for(i=1;i<=NF;i+=2) print $i}' /etc/passwd
[root@rs1 ~]# netstat -ant | awk '$1~/tcp/{S[$NF]++}END{for (A in S) print A,S[A]}'
[root@rs1 ~]# awk -F: '$NF!~/^$/{SHELL[$NF]++}END{for(A in SHELL) print A,SHELL[A]}' /etc/passwd
[root@rs1 httpd]# awk '{IP[$1]++}END{for (A in IP) print A,IP[A]}' access_log.1
五、case
語法:switch (expression) { case VALUE or /REGEXP/: statement1, statement2,... default: statement1, ...}
六、break 和 continue
經常使用於循環或case語句中
七、next
提早結束對本行文本的處理,並接着處理下一行
awk中使用數組:
array[index-expression]
index-expression能夠使用任意字符串;須要注意的是,若是某數據組元素事先不存在,那麼在引用其時,awk會自動建立此元素並初始化爲空串;所以,要判斷某數據組中是否存在某元素,須要使用index in array的方式。
用法示例:
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
每出現一被/^tcp/模式匹配到的行,數組S[$NF]就加1,NF爲當前匹配到的行的最後一個字段,此處用其值作爲數組S的元素索引;
awk '{counts[$1]++}; END {for(url in counts) print counts[url], url}' /var/log/httpd/access_log
用法與上一個例子相同,用於統計某日誌文件中IP地的訪問量
awk的內置函數:
split(string, array [, fieldsep [, seps ] ])
功能:將string表示的字符串以fieldsep爲分隔符進行分隔,並將分隔後的結果保存至array爲名的數組中;
netstat -ant | awk '/:80/{split($5,clients,":");IP[clients[1]]++}END{for(i in IP){print IP[i],i}}' | sort -rn | head -50
length([string])
功能:返回string字符串中字符的個數;
substr(string, start [, length])
功能:取string字符串中的子串,從start開始,取length個;start從1開始計數;
system(command)
功能:執行系統command並將結果返回至awk命令
systime() 功能:取系統當前時間