gawk 文本處理入門用法詳集
gawk - pattern scanning and processing language
報告生成器,可進行格式化輸出,文本處理三劍客之一,是基於sed和grep功能的擴展
一般用法格式:
awk [options] ‘program‘ FILE... program: /regular/{print}
語句之間用分號分隔
print,printf
選項:
-F:指明輸入時用到的字段
-v var=value:指明自定變量
awk運作方式:
逐行讀入文本,並將每個字段給予一個變量進行存儲,$1..$NF ,而$0標識一整行
顯示文本的的2,4字段,默認是空格為分隔符,默認輸出以空格為分隔符
tail -3 /etc/fstab | awk ‘{print $2,$4}‘
1.print item1,item2...
以逗號作為分隔符 變量的引用,不允許在""內部 省略item,則默認print $0
2.變量
1.內鍵變量
FS:input field seperator指明輸入字段分隔符類似-F
OFS:output field seprator 指明輸出字段分隔符
RS:input record seperator輸入時的換行符
]# awk -v RS=‘ ‘ ‘{print}‘ /etc/passwd
ORS:output record seperator輸出時的換行符
NF:number of field,每行的字段數量
$NF:最後一個字段
NR:number of record,行數
FNR:各文件分別計數
FILENAME:當前的文件名
ARGC:命令行參數的個數(program 不為參數)
]# awk ‘BEGIN{print ARGC}‘ /etc/fstab
ARGV:數組,保存,命令行中所給定的每個字段
2.自定義變量
-v var=value
變量名區分大小寫
]# awk -v test=‘hello gawk‘ ‘BEGIN{print test}
在program中直接定義
]# awk ‘BEGIN{test="hello gawk";print test}‘
3.printf命令:格式化輸出
printf "FORMAT1,FORMAT2",item1,item2... ===>FORMAT與item對應位置的格式化 1.FORMAT是必須要給出 2.printf不自動換行,顯式給出換行符\n 2.FORMAT需要分別為後面的每個item指定一個格式化符號
格式符(需用雙引號):
%c :顯示字符的ASCII碼 %d %i:顯示十進制整數 %e %E:科學計數法數值顯示 %f:顯示浮點數 %g,%G:以科學計數法或浮點數顯示數值 %s:顯示字符串 %u:無符號整數 %%:顯示%自身
格式化輸出示例:
]# awk -F: ‘{printf "Username: %s\n",$1}‘ /etc/passwd
修飾符:加在格式符之前,用於控制格式符的顯示方式
#.# 第一個數字控制顯示寬度;第二個#表示小數點後的精度
%3.2f - : 顯示為左對齊 + : 顯示數值的符號,有正數負數之分
示例:
]# awk -v FS=‘:‘ ‘{printf "username: %-25s,UDI: %-25d\n",$1,$3}‘ /etc/passwd
4.操作符
算術操作符
x+y,x-y,x*y,x^y,x/y,x%y -x:正數轉化為負數 +x:字符串轉化為數值
字符串操作符:沒有符號的操作符,字符串的連接
賦值操作符: =,+=,-=,*=,/=,%=,^= ++,-- 比較操作符: >,<,>=,<=,!=,== 模式匹配符: ~:是否匹配 !~:是否不匹配 邏輯操作符: && || !
函數調用:
function_name(argu1,argu2,...) 條件表達式:(三目運算) selctor?if-true-expression:if-false-expression
示例:查找本機的普通用戶及系統用戶
# awk -F: -v OFS=":" ‘{$3>1000?usertype="common user":usertype="system user";printf "%-18s,%s\n",$1,usertype}‘ /etc/passwd
5.PATTERN
1 .empty:空模式,匹配每一行
2 ./regular expression/:文本過濾僅處理被模式匹配到的行
]# awk ‘/^UUID/{print $1}‘ /etc/fstab
3 .relatinal expression:關系表達式:結果為真式,才會被處理;非零為真
]# awk -F: ‘$3>=1000{print $1,$3}‘ /etc/passwd
查找其用戶的默認shell為/bin/bash的用戶
]# awk -F: ‘$NF=="/bin/bash"{print $1,$NF}‘ /etc/passwd ]# awk -F: ‘$NF~/bash$/{print $1,$NF}‘ /etc/passwd
4 .lines ranges:行範圍
startline,endline
註意:不支持直接指定數字,可以容如下方式
]# awk -F: ‘(NR>=2&&NR<=5){print $1,$2}‘ /etc/passwd /part1/,/part2/ ]# awk -F: ‘/^h/,/^9/{print $1}‘ /etc/passwd
5 .BEGIN/END模式:處理開始之前處理一次
BEGIN{}:僅在開始處理文件中的文件之前執行一次:
END{}:僅在文本處理完成之後執行一次
]# awk -F: ‘BEGIN{print "username uid \n----------"}{print $1,$3‘ /etc/passwd
6 .常用的action:
1.expressions 2.control statements:if ,while,等; 3.compound statements:組合語句; 4.input statements 5.output statements
7 .控制語句
if(condition) {statements} else {statments} while(condition) {statements} for(expr1;expr2;expr3) {statements} {statements}組合語句需要{}
if-else
語法: if(condition) statements [else statements]
]# awk -F: ‘{if($3>=1000) {printf "common user:%s\n",$1} else {printf "system user: %s\n ",$1}}‘ /etc/passwd
取得磁盤利用率:
]# df -h| awk -F [%] ‘/^\/dev/{print $1}‘|awk ‘{if($NF>=10) print $1}‘
while循環:
語法:while(condition) statements
條件為"真",進入循環;條件為假則退出循環
使用場景:對一行內的多個字段逐一處理,對數組中的字段做逐一處理函數:length()字符長度
統計每個字段的長度?
~]# awk ‘/[[:space:]]*linux16/{i=1;while(i<=NF) {print $i,length($i);i++}}‘ /etc/grub2.cfg
並統計出大於7的字段?
~]# awk ‘/[[:space:]]*linux16/{i=1;while(i<=NF) {if(length($i)>=7) {print $i,length($i)};i++}}‘ /etc/grub2.cfg
do-while循環
語法:do statement while(condition) 意義:先執行循環語句,而後在判斷執行while循環
for循環:
語法:for(expr1;expr2;expr3) statement
for(variable assignment;condition;iteration proccess) {for-body}~]# awk ‘/[[:space:]]*linux16/{for(i=1;i<=NF;i++) {print $i,length($i)}}‘ /etc/grub2.cfg
特殊用法:
能夠遍歷數組中的元素:for(var in array) {for-body}
switch語句:
語法: switch(expression) {case VALUE1 or /REGEXP/:statement;case VALUE2 or /REGEXP/:statement...;default statement}
break和continue
break [n] :跳出n層循環
next
提前結束對本行的處理而直接進入下一行 僅顯示偶數的uid用戶? ~]# awk -F: ‘{if($3%2!=0) next; print $1,$3}‘ /etc/passwd
array
關聯數組:array[index-expression]index-expression: 1.可使用任意字符串;索引要使用雙引號"";array["mon"]=Monday 2.如果某元素事先不存在,在引用時awk會自動將此元素創建並將其賦值為空串
若要判斷數組中是否存在某元素,要使用"index in array"格式進行
若要遍歷數組中的每個元素,要使用for循環:
for(var in array) {for-body}
~]# awk ‘BEGIN{weekdays["mon"]="monday";weekdays["tue"]="tuesday";for(i in weekdays) {print weekdays[i]}}‘ 註意:var會遍歷array的每個索引;
查看netstat -nat中tcp狀態出現的次數?
~]# netstat -tan |awk ‘/^tcp\>/{state[$NF]++}END{for(i in state) {print i,state[i]}}‘
查看ss -nat中tcp狀態出現的次數?
~]# ss -tan |awk ‘{state[$1]++}END{for(i in state) {print i,state[i]}}‘
查看ip地址的訪問量?
~]# awk ‘{ip[$1]++}END{for(i in ip) {print i,ip[i]}}‘ /var/log/httpd/access_log
統計/etc/fstab中文件系統的個數?
~]# awk ‘/^UUID/{fs[$3]++}END{for(i in fs) {print i,fs[i]}}‘ /etc/fstab
統計指定文件中每個單詞出現的次數?
~]# awk ‘{for(i=1;i<=NF;i++) {count[$i]++}}END{for(i in count) {print i,count[i]}}‘ /etc/fstab
9.內置函數:
數值處理: rand():返回指定字符串的長度; 字符處理: length([s]):返回指定字符串的長度; sub(r,s,[t]):以r表示模式查找t所表示的字符中匹配的內容,並將其第一次出現替換為s所表示的內容; gsub(r,s,[t]):以r表示模式查找t所表示的字符中匹配的內容,並將全局出現替換為s所表示的內容; splits(s,a[,r]):以r為分隔符切割字符s,並將切割後的結果保存至a所代表的的數組中
統計ip地址出現的次數?
~]# netstat -tan|awk ‘/^tcp\>/{split($5,ip,":");count[ip[1]]++}END{for(i in count) {print i,count[i]}}
本文出自 “老城小敘” 博客,請務必保留此出處http://cityx.blog.51cto.com/9857477/1927819
gawk 文本處理入門用法詳集