下面介紹的是三種文本處理工具之一-----------------awk
文本處理三劍客爲grep、sed(流編輯器)、awk(報告生成器)。awk來源于貝爾實驗室的三個人,三個字母分別提取自名字。
1、awk基礎
(1)awk命令簡介
格式:awk [options] 'program' file...
program:即 pattern{action statements;...},其中pattern(BEGIN、END),action statement(print、printf)
常用選項:
-F -----------指明字段分隔符,默認爲空白字符
-v var=value -----------自定義變量,爲自定義變量賦初始值
例:awk [options] 'pattern{action statements;...}' file...
awk默認使用內置位置變量來存儲各個字段的值,即$1、$2、...$N。使用$0保存整行的內容。
awk默認的分隔符爲空白字符。
(2)、awk工作原理
1)、執行BEGIN{action statements} ----------awk開始之前執行,可選
2)、執行pattern{action statements} --------逐行讀取、逐行重複,可選
3)、執行END{action statements} -------------退出awk之前執行,可選
2、awk命令 ----------變量
awk的變量分爲兩種,即:內建變量、自定義變量。
常用的10個變量介紹和示例如下:
(1)、print:標準格式顯示。---------默認各個字段用逗號分隔
print item1,item2... -------如果省略item,輸出整行,相當於{print $0},輸出整個文件
(2)、FS -----------輸入字段分隔符,默認空白字符
OFS ----------輸出字段分隔符,默認空白字符
例:
# awk -v FS=':' -v OFS=':' '{print $1,$3}' /etc/passwd
例:
# echo -e "1 2 3\n4 5 6\n7 8 9" | awk -v FS=' ' '{print $1}' -----------自定義分隔符
# echo -e "1 2 3\n4 5 6\n7 8 9" | awk -v FS=' ' -v OFS='@' '{print $1,$2}'
1@2
4@5
7@8
(3)、RS --------------輸入記錄分隔符,默認換行符
ORS --------------輸出記錄分隔符
例:
# awk -v RS='/' '{print $0}' /etc/passwd
例:
# echo -e "1 2 3 4@5 6 7 8 9" | awk -v RS='@' '{print $0}'
1 2 3 4
5 6 7 8 9
# echo -e "1 2 3 4@5 6 7 8 9" | awk -v RS='@' -v ORS='/' '{print $0}' ---------$0代表整行
1 2 3 4/5 6 7 8 9
(4)、NF --------------字段數量,內建
例:
# echo -e "1 2 3 4@5 6 7 8 9" | awk '{print NF}'
8 -------------顯示字段數
# echo -e "1 2 3 4@5 6 7 8 9" | awk '{print $NF}'
9 ------------顯示最後一個字段具體的內容
例:
例:
# awk -v FS=':' '{print NF}' /etc/passwd
# awk -v FS=':' '{print $NF}' /etc/passwd
# awk -v FS=':' '{print $(NF-1)}' /etc/passwd
(5)、NR -------------輸出每次遍歷的行數,可以理解爲行號
例:
# echo -e "1 2 3 4\n5 6 7 8 9" | awk '{print NR}'
1
2
(6)、FNR ---------輸出每個文件的行數,分別統計
例:
# echo -e "1 2 3 4\n5 6 7 8 9" | awk '{print NR}'
1
2 --------------若是文件衆多的話,不會接上,是重新分別統計。
(7)、FILENAEM ------------輸出文件名
例:
# echo -e "1 2 3 4\n5 6 7 8 9" | awk '{print FILENAME}'
-
-
(8)、ARGC --------------輸出命令行參數,命令本身算一個
例:
# echo -e "1 2 3 4\n5 6 7 8 9" | awk '{print ARGC}'
1
1
# awk '{print ARGC}' /etc/passwd
2
...
(9)、ARGV ---------------調用數組
例:
# awk '{print ARGV[1]}' /etc/passwd /etc/issue
/etc/passwd
/etc/passwd
(10)、varl="VALE" ----------自定義變量
# awk -v varl='hello' -F ":" '{print varl ,$1}' /etc/passwd --------------varl ,$1(之間可以有空格,也可以沒有 )
hello root
hello bin
3、awk命令 ------------printf
awk中的printf命令,是格式化輸出命令,默認不自動換行,需要顯式給出換行控制符(\n)
格式:printf "FORMAT" item1,item2,...
格式符:
%c -----------ASCII碼顯示
%d,%i ---------十進制整數顯示
%f -----------浮點數顯示
%e、%E -----------科學計數法顯示【數字】
%g、%G ----------科學計數法顯示【浮點數字】
%s -----------顯示字符串
%u ------------顯示無符號整數
%% ---------------顯示%自身
修飾符:#[.#]
#[.#]的第一個數字用來控制顯示【寬度】,第二個數字表示小數點的【精度】。
例:%3.1f %5s
#[.#]中,加入+、-有特殊意義,具體如下:
-:表示採用左對齊機制,默認是右對齊。例:%-15s
+:顯示數字的正負符號。例:%+d
例:
# awk -F: '{printf "%-20s: %-5s\n",$1,$3}' /etc/passwd
4、awk命令 -------------操作符
# awk -F: '$3==1000{print $0}' /etc/passwd
# awk -F: '$NF~/bash/{print $0}' /etc/passwd -----------匹配(!~不匹配)
# awk -F: '$3>=500&&$3<=1000{print}' /etc/passwd ----------與或非
# awk -F: '{$3>=1000?usertype="Common User":usertype="Super or System User";printf "%-20s: %-20s\n",usertype,$1}' /etc/passwd ------------條件表達式
5、awk命令 ------------匹配模式(5種)
(1)、empty ---------空模式,處理每一行
(2)、[!]/REGEXP/ ---------------是否PATTERN匹配到的行
例:
# awk '[!]/^r/{print}' /etc/passwd
(3)、關係表達式
例:$3>=1000, $NF~/bash/
(4)、/regexp1/,/regexp2/ -------regexp1到regexp2的行,有多少這一類匹配結果,就顯示多少次
例:($3>=500&&$3<=1000)
例:
# awk '/^r/,/^a/{print}' /etc/passwd
(5)、BEGIN/END模式:
BEGIN{} ----------開始處理時,第一行文本之前執行一次
例:
# awk -F: 'BEGIN{printf "%20s %5s\n","Username","UserID"}{printf "%20s %5s\n",$1,$3}' /etc/passwd
注意:在輸出特定格式的表頭時,常用此語句塊;
END{} ------------文本處理完成,命令尚未退出時,執行一次
例:
# awk -F: 'BEGIN{printf "%20s %5s\n","Username","UserID"}{printf "%20s %5s\n",$1,$3}END{print "========================\n",NR " users"}' /etc/passwd
6、awk命令 ---------------控制語句(6個)
(1)、 if-else -----------條件判斷
例:
# awk -F: '{if($3>=1000) {print $1} else {print $1,$3}}' /etc/passwd
(2)、while循環 ------------對一行內的多個字段逐一處理時、遍歷數組
例:
# awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {printf "%s: %d\n",$i,length($i);i++}}' /etc/grub2.cfg
(3)、do...while循環 -----------至少執行一次循環體中的語句
(4)、for循環:
例:
# awk '/^[[:space:]]*linux16/{for(i=1;i<=NF;i++) {printf "%s: %d\n",$i,length($i)}}' /etc/grub2.cfg
(5)、break、continue
break [n]
continue ---------------跳過本次循環,直接進入下一次循環
(6)、 next ----------提前結束本行,直接進入下一行
例:
# awk -F: '{if($3%2!=0) next;print $1,$3}' /etc/passwd
7、awk命令 ---------------數組
awk關聯數組,使用字符串時,字符串必須使用【雙引號】。如果某數組元素事先不存在,當引用該元素時,awk會【自動創建】此元素,並且爲該元素賦"空字符串"作爲其初始值。
例:
# awk 'BEGIN{name["leader"]="zhang";name["mem1"]="li";name["mem2"]="wang";print name["leader"]}'
# ss -tn | awk '/^ESTAB\>/{print $NF}' | awk -F: '{state[$1]++}END{for(s in state){print state[s],s}}' ------------查看已連接狀態下,同一客戶端的連接數量