1. 程式人生 > >十五 awk文本處理

十五 awk文本處理

進行 BE 系統用戶 字符串 ces vim 數量 內置變量 image

awk編程語言/數據處理引擎

創造者:Aho、Weinberger、Kernighan
基於模式匹配檢查輸入文本,逐行處理並輸出
通常用在Shell腳本中,獲得指定的數據
單獨用時,可對文本數據做統計

基本用法

語法格式

前置命令 | awk [選項] ‘[條件]{編輯指令}‘
awk [選項] ‘[條件]{編輯指令}‘ 文件
在編輯指令中,若有多條語句,可用分號分隔,print是最常用的指令

常用命令選項

命令選項    註釋
-F    指定分隔符,可省略(默認空格或Tab位);符號分隔需要用雙引號""
括起來 -f 調用awk腳本進行處理 -v 調用外部Shell變量

技術分享圖片

處理動作

print     打印,相當於shell中的echo
,      多個參數用逗號分隔
;      多個動作用分號;分隔

awk執行過程

以行為處理單位
對數據進行逐行處理
處理完當前行,把當前行的處理結果輸出後自動對下一行進行處理 直到文件中所有行處理完為止

awk內置變量

直接含義,可直接使用

調用變量的時候不用$符號標示,直接調用就可以

變量        用途
FILENAME     當前處理文件的文件名
$
0    當前讀入的整行文本內容 NR    記錄當前已讀入行的數量(行數) FNR    保存當前處理行在原文本內的序號(行號) NF    記錄當前處理行的字段個數(列數) $n     指定分隔的第n個字段,如$1、$3分別表示第1、第3列 FS     保存或設置字段分隔符,例如FS=":" ENVIRON 調用Shell環境變量,格式為:ENVIRON["變量名"]

awk處理時機

BEGIN{}:行前處理      讀入第一行文本之前執行;一般用來初始化操作
                可選操作,可以有多個
{ }:逐行處理          逐行讀入文本執行相應的處理;可選操作
                是最常見的編輯指令塊
END{}:行後處理        處理完最後一行文本之後執行;可選項
               一般用來輸出處理結果

註意:可單獨使用,也可同時使用

例子: awk‘BEGIN{FS=":";print NR} {print NR,$0}END{print NR}‘ a.txt

技術分享圖片

awk處理條件

默認awk對讀入的每行進行處理,如想只處理指定行時就需要加要條件判斷。

awk [選項] ‘[條件]{處理動作}‘ 文件

條件的表現形式

正則表達式
數值或字符串比較
邏輯比較
運算符

使用正則條件

~匹配:結果匹配正則表達式為真
!~不匹配:結果不匹配正則表達式為真

技術分享圖片

使用數值比較

操作符    含義
==    等於;用於字符比較時要加 "" 雙引號 
!=    不等於;用於字符比較時要加 "" 雙引號
>     大於
>=    大於或等於
<     小於
<=    小於或等於

技術分享圖片

技術分享圖片

邏輯比較

操作符    
&&邏輯與    期望多個條件都成立
||邏輯或    只要有一個條件成立即滿足要求

技術分享圖片

變量的運算

運算符
+、-、*、/、%
++、--、+=、-=、*=、/=
^或**(乘方)

技術分享圖片

技術分享圖片

技術分享圖片

awk流程控制

awk流程控制分類

分支結構

單分支
雙分支
多分支

循環結構

while 
do...while
for

分支結構

單分支

if(條件){編輯指令}

例子

 awk -F ":" {if($3==1){print $0;print NR}} /etc/passwd

雙分支

if(條件){編輯指令1}else{編輯指令2}

例子

awk -F":"   { if($3<500){i++}else{j++} }END{print i;print j  }  /etc/passwd

多分支

if(條件){編輯指令1}else{編輯指令2}....else{編輯指令N}

技術分享圖片

while循環結構

while循環

while (條件){編輯指令}

do while循環

do{編輯指令}while(條件)

技術分享圖片

for循環結構

for循環

for(初值;條件;步長){編輯指令}

例題:

awk BEGIN{for(i=0;i<=10;i++){print i}}

主要的控制語句

關鍵字    含義
break    結束當前的循環體
continue    中止本次循環,轉入下一次循環
next    跳過當前行,讀入下一行文本開始處理
exit    結束文本讀入,轉入END{}執行
    如果沒有END{}則直接退出awk處理操作

技術分享圖片

用awk腳本處理文件
[root@localhost ~]# cat test.awk 
#!/bin/awk -f
BEGIN{
FS=":"
i=0
j=0
}

{
   if($3<500){
     i++

}else{
    j++
}
}

END{
print "系統內建用戶有 " i ""
print "系統外建用戶有 " j ""
}



例題:
awk -F":" { while($3<3){print $1,$3;$3++} } /etc/passwd 
awk -F":" {while($3<3){print $1,$3;$3=3}} /etc/passwd

awk BEGIN{ i=1;while(i<=10){if(i%2==0){print i};i++} }

awk BEGIN{i=0}{i++}END{print i} /etc/passwd

用awk統計文件數據

vim testa.awk
#!/bin/awk -f
BEGIN{
FS=":"
i=0
j=0
}

{
if($3<500){
        i++
}else{
        j++
}
 }

END{
print i
print j

}

awk數組

定義數組

數組名[數組元素下標]=元素值

輸出數組元素print

數組名[數組元素下標]

如:

awk -F ":" {usergrp[$3]=$1;print usergrp[$3]} /etc/passwd
    awk BEGIN{usergrp[0]="yzs";usergrp[1]="lucy";print usergrp[0]}

遍歷(輸出)數組的循環結構:

for(變量名 in  數組名){print 數組名[變量]}

例子:

awk BEGIN{usergrp[0]="yzs";usergrp[1]="lucy";for( i in usergrp){print usergrp[i]}}

        awk BEGIN{ for(i=1;i<=10;i++){name[i]=i};for(j in name){print name[j]}  }

數組作業

把當前系統使用頻率最高的前10條命令輸出

awk  { comm[$1]++}END{for( i  in  comm){print  i,comm[i]}}  /root/.bash_history   |  sort  -rnk   2   |   head

其中各個命令的含義:

comm[$1]++} :$1是文件中的第一列  ++ 當第一列數據相同時自加1
END{for( i  in  comm)  
{print  i,comm[i]}} 
 /root/.bash_history  
|  sort  -rnk   2   
|   head

2 、輸出當前系統1小時內占用CPU最多的前10個進程

#!/bin/bash
for((i=0;i<60;i++))
do
    ps   -eo   comm,pcpu  |  tail   -n   +2   >>  /tmp/top10.txt
    sleep  60
done
awk { process[$1]+=$2}END{for(  j   in  process){ print  i,process[i]}}  /tmp/top10.txt   |  sort  -rnk    2  | head

awk練習題:

1、只顯示uid是501的用戶的詳細信息
awk -F ":" $3=="501"{print $0} /etc/passwd



2、輸出文件中偶數行的內容
awk FNR%2!=1{print $0} a.txt 


3、統計系統內有多少個用戶不能登錄系統
 awk -F ":" $7~"no"{print $0;i++}END{print i} /etc/passwd

41-100間 是7的倍數或是含7的數顯示出來
awk FNR%7==0{print $0}{print FNR} /etc/passwd



5、統計當前系統有多少個內建帳戶


6、統計當前系統有多少個自定義帳戶
awk -F ":" BEGIN{i=0;j=0}$3<500{i++}$3>=500{j++}END{print "uid 小於 500的用戶有 "i"個";print "uid 大於等於 500的用戶有"j"個"}  /etc/passwd

7、把用戶名含數字的用戶信息輸出
awk -F ":" $1~/[0-9]/{print $0} aa.txt

8、顯示前5個系統用戶的用戶名、uid、shell

十五 awk文本處理