awk:報告生成器,格式化文本輸出
基本用法:
gawk [options] 'program' FILE …
options:
-F:指明輸入時用到的字段分隔符;從文本中讀取數據時,以什么當做分隔符;
-v var=value:自定義變量
awk引用變量的值時,不應該加$
program:PATTERN{ACTION STATEMENTS} 語句之間用分號分隔
1.print
print item1,item2:多字段之間需使用逗號隔開
要點:①逗號分隔符
②輸出的各item可以是字符串,也可以是數值,也可是當前記錄的字段、變量或awk的表達式;
③若省略 item,相當于print $0,將源文件的中的文件全都打印到屏幕上來;
用法:
原來/etc/fstab中的內容:
tail -4 /etc/fstab | awk '{print $2,$3}':打印/etc/fstab文件當中的第二列和第三列內容;
tail -4 /etc/fstab | awk '{print "hello",$2}':在打印的每行字符前面添加hello
tail -4 /etc/fstab | awk '{print ""}':將每行都打印為空行
tail -4 /etv/fstab | awk '{print }' 或 tail -4 /etc/fstab | awk '{print $0}':相當于顯示所有的行的內容
2.變量
①內建變量:
FS:input field seperator:默認為空白字符;
OFS:output field seperator:默認為空白字符;
awk -v FS=':' -v OFS='\t' '{print $1,$3,$7}' /etc/passwd:以:為輸入字段的分割符,以\t(tab)為輸出的分割符,對于指定的顯示字段;
RS:input record seperator:輸入時的換行符;
ORS:output record seperator:輸出時的換行符;
NF:number of field:字段數量
eg:awk '{print NF}' /etc/fstab:顯示該行有幾個字段
awk '{print $NF}' /etc/fstab:顯示該行最后一個字段的內容
NR:number of record:打印每一個文件的行數
FNR:對于以后的n個文件分別計數行數;
FILENAME:顯示當前正在處理的文件名,默認每行都顯示文件名
ARGC:命令行中參數的個數;
ARGV:數組,保存的是命令行給定的各參數;
②自定義變量:
-v var=value:變量名區分字符大小寫
在program中直接進行定義
3.printf命令:
格式化輸出:printf FORMAT,item1,item2,…
FORMAT:為占位符,item1,item2,按照指定的格式
①FORMAT必須給出;
②不會自動執行,需要顯示給出執行控制符,\n
③FORMAT中需要分別為后面的每一個item指定一個格式化的符號
awk -F: '{printf "Username: %s UID: %d\n",$1,$3}' /etc/passwd
按行顯示,/etc/passwd文件中的第一個字符段;$1顯示的為前面%s的格式,$3顯示的為前面%d格式顯示
格式符:
%c:顯示字符的ASCII碼;
%d,%i:顯示十進制整數;
%e,%E:科學計數法數值顯示;
%f:顯示為浮點數;
%g,%G:科學計數法或浮點形式顯示數值
%s:顯示字符串
%u:無符號整數
%%:顯示%自身
修飾符:
#[.#]:第一個數字控制顯示字符的寬度,第二個#表示顯示小數點之后的精度; %3.1f:顯示字符寬度為3,小數點后精確到0.1
-:左對齊
+:顯示數值的符號
4.操作符:
算數操作符:
x+y,x-y,x*y,x/y,x^y,x%y
-x
+x:轉換為數值;
字符串操作符:沒有符號的操作符,字符串連接
賦值操作符:
=,+=,-=,*=,/=,%=,^=
++,–
比較操作符:
>,>=,<,<=,!=,==
模式匹配符:
~:左側的字符串是否被右邊的模式所匹配 !~:是否不匹配
邏輯操作符:
&&:邏輯與
|| :邏輯或
函數調用:
function_name(argu1,argu2, …)
內建的條件表達式:
selector?if-ture-expression:if-false-expression
#awk -F: '{$3>=500?usertype="Common User":usertype="Sysadmin or SysUser";printf "Username:%15s:Usertype:%s\n",$1,usertype}' /etc/passwd
5.PATTERN:
(1)empty:空模式,為awk處理的默認方式,默認處理為全部處理;
(2)/reguler expression/:僅處理能夠被此處的模式匹配到的行;
awk '/^UUID/{print $0}' /etc/fstab
awk '!/^UUID/{print $0}' /etc/fstab
(3)relational expression:關系表達式,結果有“真”有“假”,結果為“真”,才會被處理;
真:結果為非0值;非空字符串也為假。
awk -F: -v OFS=':' '$3>=500{print $1,$3,$7}' /etc/passwd
awk -F: '$NF=="/bin/bash"{print $1,$NF}' /etc/passwd
awk -F: '$NF~/bash$/{print $1,$7}' /etc/passwd
awk -F: '$7=="/bin/bash"{print $1,$7}' /etc/passwd
(4)line ranges:行范圍:
startline,endline:/part1/,/part2/
注意:不支持直接給出數則的格式顯示,要想使用數字方式顯示,可使用下面的方式:
awk -F: '(NR>=2&&NR<=10){print $1}' /etc/passwd
awk -F: '/^h/,/^s/{print $1}' /etc/passwd
(5)BEGIN/END模式:
BEGIN():僅在開始處理文件中的文本之前執行一次;
awk -F: 'BEGIN{print "This is a test."}{print $0}' /etc/passwd
END():僅在文本處理完成之后執行一次;
awk -F: 'END{print "This is a test."}{print $0}' /etc/passwd
6.常用的action:
(1)Expressions:表達式
(2)Control statements:if,while等:
(3)Compound statements:組合語句:
(4)input statements:輸入語句;
(5)output statements:輸出語句;
7.控制語句:
(1)if-else:
if(comdition) {statements}
awk -F: '{if($3>=500) print $1,$3}' /etc/passwd
if(comdition) {statements} else {statements}
awk -F: '{if($3>=500) {printf"Common user:%s\n",$1} else {printf"root or Sysuser:%s\n",$1}}' /etc/passwd
(2)while
while(comdition) {statements}
條件“真”,進入循環,條件“假”,退出循環,循環體可能一次也不會執行;
使用場景,隊一行內的多個字段逐一類似處理時使用,對數組中的各元素逐一處理時使用;
(3)do-while循環;
do {statements} while(comdition)
意義:至少循環一次循環體
(4)for循環:
for(expr1;expr2;expr3) {statements}
特殊用法:能夠遍歷數組中的元素
awk '/^[[:space:]]*linux64/{for(i=1;i<=NF;i++){print $i,length($i)}}' /etc/grub2.cfg
(5)switch-case語句;
語法:switch(expression) {case VALUE1 or /REGXP/:statement;case VALUE2 or /REGXP/:statement;…..;default:statement}
(6)break和continue:
break [n]:結束當前循環
continue:
(7)next:
提前結束對本行的處理,直接進入下一行;
awk -F: '{if($3%2!=0) next;print $1,$3}' /etc/passwd
(8)array
關聯數組:array[index-expression]
index-expression:
(1)可使用任意字符串;字符串要使用雙引號;
(2)如果某數組元素事先不存在,在引用時,awk會自動創建此元素,并將其值初始化為"空串"。
若要判斷數組中是否存在元素,要使用"index in array" 格式進行;
變量賦值:weekdays[mon]="Monday"
若要遍歷數組中的每個元素,要使用for循環;
for(var in array){for-body}
awk ‘BEGIN{weekday=["mon"]="monday";weekday["tue"]="Tuesdays";for(i in weekday) {print}}'
awk '{ip[$i]++}END{for(i in ip) {print i,ip[i]}}' /varl/log/httpd/access_log
注意:var會遍歷array的每個索引;
-tan | awk '/^tcp\>/{state[$NF]++}END{for(i in state){print i,state[i]}}'
delete array[index]
delete array
exit
8.函數:
(1)內置函數:
數值處理:
rand():返回0和1之間的一個隨機數
字符串處理:
length([s]):返回指定字符串的長度
sub(r,s,[t]):以r表示的模式來查找t所表示的字符串中的匹配的內容,并將其第一次出現替換為s所表示的內容;
gsub(r,s,[t]):以r表示的模式來查找t所表示的字符串中的匹配的內容,并將其所有出現替換為s所表示的內容;
split(s,a,[r]):以r為分割符切割字符s,并將切割后的結果保存至a所表示的數組中;
(2)自定義函數:
原創文章,作者:sjsir,如若轉載,請注明出處:http://www.www58058.com/47915
awk是一個很方便的文本格式化工具,這也是以后面試題必會遇到的面試題,希望下來多加練習,熟練掌握,