Linux系統——awk命令


awk命令不僅僅是Linux系統的命令,也是一種編程語言,用來處理數據和生成報告(Exel),處理的數據可以是一個或多個文件(標准輸入和管道獲取標准輸入)。可在命令行上編輯操作,也可以寫成awk程序運用。

 

查看awk版本

# awk  --version

 

awk格式

# awk  -F “參數”  ‘BEGIN{} 模式 {動作} END{}’ 文件路徑

參數

-F 指定awk按照什么符號進行文本切割,將原文件內容切割成一列一列,如果不指定-F參數,awk默認按照空格進行文本切割

{} 代表print輸出 輸出多個值用逗號“,”分隔;{}中雙引號里的內容原封不動輸出

$ 代表取列

$1 代表第一列,以此類推 $0表示所有內容 $NF表示輸出最后一列(最后一組元素)

 

BEGIN{}:告知awk,數據要如何讀取

END{}:告知awk,程序要如何結束

awk指令是由模式、動作,或者模式和動作的組合組成。

awk  [awk參數]  模式 {動作}’ 文件名

 

模式:過濾條件

動作:執行

在指定文件中,awk先根據分隔符進行切割,再在模式中過濾所需的數據,再通過動作去執行(無動作時,默認輸出全部內容)

# awk -F “: ” ‘NR==3{print $1}’ yunjisuan.txt

 

 

awk執行過程

BEGIN模塊開始,一行一行讀數據,看模式,是否符合條件,符合則執行動作;若不符合,則執行下一行。執行到結尾,會執行END模塊后輸出文本內容

1awk讀入第一行內容

2)判斷是否符合模式中的條件NR>=2

a,如果匹配則執行對應的動作{print $0}
b,如果不匹配條件,繼續讀取下一行

3)繼續讀取下一行
4)重復過程1-3,直到讀取到最后一行(EOFend of file

 

分隔符

通過-F參數指定分隔符,換行符默認\n

NR這個符號的真正含義不是行號,二十數據被awk讀取一段以后,NF就會記錄一次。

由於awk默認以\n作為每次讀取數據的結束標志,NR就恰好等於行號。

 

awk的換行符

通過BEGIN{},在awk讀取數據之前設定它的讀入換行符、輸出換行符;通常,默認awk的讀入換行符和輸出換行符為\n

RS 是輸入記錄分隔符,決定awk如何讀取或分隔每行(記錄)

ORS表示輸出記錄分隔符,決定awk如何輸出一行(記錄)的,默認是回車換行(\n

FS是輸入區域分隔符,決定awk讀入一行后如何再分為多個區域。

OFS表示輸出區域分隔符,決定awk輸出每個區域的時候使用什么分隔他們。

awk無比強大,你可以通過RSFS決定awk如何讀取數據。你也可以通過修改ORSOFS的值指定awk如何輸出數據。

 

 

更改換行符,用RSORS操作

RS=””讀入換行符(輸入輸出數據記錄分隔符) ORS=””輸出換行符(輸出記錄分隔符) NR 記錄行號

 

當更改輸出換行符時,輸出換行符會替換掉讀入換行符

 

因為設定了讀入換行符RS=”:”,因此,在awk的內存里的數據是按照如下排列的:

1 root

2 x

3 0

4 0

5 root

6 /root

7 /bin/bash\nbin

8 x

9 1

10 1

 

由於awk默認輸出換行符是\n,因此在輸出時,awk會在內存行的每行結尾附加輸出換行符號\n,因此輸出時效果如下:

1 root

2 x

3 0

4 0

5 root

6 /root

7 /bin/bash

Bin

8 x

9 1

10 1

  

按單詞出現頻率降序排序(計算文件中每個單詞的重復數量)

 方法(1)將所有非小寫字母和非大寫字母替換成空,剩余都是英文單詞,再計數並排序

# cat count.txt | xargs -n1 | sort | uniq -c | sort -rn

 

引申:

sort 默認按26個字母排序(默認指定排序為第一列)

sort -n 按照數字大小排序

sort -r 倒序排序

sort -k 數字 從第“數字”列,按大小排序

 

uniq 相同元素去重

uniq -c 去重並計數

 

替換tr

# tr  “”  “”

tr “a-z” “A-Z” 轉換大小寫

tr “:” ”?” :替換成?

 

方法(2將文件里面的所有空格替換為回車換行符“\n” 

# cat count.txt | tr " " "\n" | sort | uniq -c | sort -rn

 

方法(3grep所有連續的字母,grep -o參數讓他們排成一列

# grep -o "[a-zA-Z]\+" count.txt | sort | uniq -c | sort

 

awk的模式分類

(1)正則表達式模式

(2)比較表達式模式

(3)范圍模式

(4)特殊模式BEGINEND

 

正則表達式模式 

顯示第9列是200的行的IP地址

# awk ‘$9~/^200$/ {print $1}’ access.log

在第9列模式下,~進行正則匹配操作,以200開頭,以200結尾過濾,

打印$1,顯示IP地址

# awk ‘$9~/^404$/ {print $1}’ access.log | sort | uniq -c

在上述基礎上,排序並去重、計數

# awk ‘$9==”404” {print $1}’ access.log | sort | uniq -c

 

awk不支持的正則符號“{}”,需要加--posix--re-interval實現

x{m}

x{m,}

x{m,n}

 

~ b表示進行正則匹配

!~ 表示與~相反

 

表示以第五列匹配正則表達式,過濾含有shutdown的字符串,顯示這一行

# awk -F “:” ‘$5~/shutdown/’ yunjisuan.txt

 

 

顯示姓zhang的人的第二次捐款金額及他的名字

# awk -F “[ :]+” ‘$1~/^zhang/ {print $2,$(NF-1)}’ /server/files/reg.txt

 

 

顯示xiaoyu的姓氏和ID號碼

# awk -F “[ : ]+” ‘$2~/^xiaoyu/ {print $1,3$}’ /server/files/reg.txt

 

 

顯示所有以41開頭的ID號碼的人的全名和ID號碼

# awk -F “[ :]+” ‘$3~/~41/ {print $1,$2,$3}’ /server/files/reg.txt

 

 

顯示所有以一個DX開頭的人名全名

# awk -F “[: ]+” ‘$2~/^d|^x/ {print $1,$2}’ /server/files/reg.txt

 

 

顯示所有ID號碼最后一位數字是15的人的全名

# awk -F “[ :]+” ‘$3~/1$|5$/ {print $1,$2}’ /server/files/reg.txt

 

 

顯示xiaoyu的捐款,每個值都有以$開頭,如$520$200$135

# awk -F “[ :]+” ‘$2~/xiaoyu/ {print “$”$4”$”$5”$”$6}’ /server/files/reg.txt 

 

 

顯示所有人的全名,以姓、名的格式顯示,如mengfeixue

# awk -F “[ :]+” ‘{print $1”,”$2}’ /server/files/reg.txt

  

 

取網卡eth0IP地址

默認分隔符,第一個字符前面不占位

指定分隔符,第一個字符前面占位

方法一:

# ifconfig eth0 | awk ‘BEGIN{RS=”[ :]”} NR==31’

 

方法二:

# ifconfig eth0 | awk -F “(addr:)|(Bcast:)” ‘NR==2{print $2}’

 

方法三:

# ifconfig eth0 | awk -F “[ :]+” ‘NR==2{print $4}’

# ifconfig eth0 | awk -F “[ :]” ‘NR==2{print $13}’

 

方法四:

# ifconfig eth0 | awk -F “[^0-9.]+” ‘NR==2{print $2}’

 

 

比較表達式模式

取出文件/etc/services23-30

# awk ‘NR>=23&&NR<=30’ /etc/services

# awk ‘NR>22&&NR<31’ /etc/services

 

判斷某一列是否等於某個字符,找出/etc/passwd中第五列是root的行

# awk -F":" '$5=="root"' /server/files/awk_equal.txt

# awk -F":" '$5~/^root$/' /server/files/awk_equal.txt

 

找出工資在(4000060000)之間的員工名字

# awk -F: ‘$3>=”40000” && $3<=”60000” {print $1}’ test2

  

范圍模式

顯示第二行到第五行的行好和整行的內容

# awk 'NR==2,NR==5{print NR,$0}' count.txt

 

顯示以bin開頭,到第五行的行號及整行內容

# awk '/^bin/,NR==5{print NR,$0}' awkfile.txt

 

從第三列以bin開始的行到以lp開頭的行並顯示其行號和整行內容

awk -F":" '$5~/^bin/,/^lp/{print NR,$0}' awkfile.txt

 

從第三列以bin開頭字符串的行到第三列以lp開頭字符串的行

# awk -F: '$5~/^bin/,$5~/^lp/{print NR,$0}' awkfile.txt

 

BEGIN模塊

(1)定義內置變量(-F本質式修改的FS變量)

# ifconfig eth0|awk -F "(addr:)|( Bcast:)" 'NR==2{print $2}'

相當於# ifconfig eth0 | awk 'BEGIN{FS="(addr:)|( Bcast:)"} NR==2{print $2}'

 

# ifconfig eth0 | awk -F "[ :]+" 'NR==2{print $4}'

相當於# ifconfig eth0 | awk 'BEGIN{FS="[ :]+"}NR==2{print $4}'

 

# ifconfig eth0 | awk -F "[^0-9.]+" 'NR==2{print $2}'

相當於# ifconfig eth0 | awk 'BEGIN{FS="[^0-9.]+"}NR==2{print $2}'

 

(2)在讀取文件之前,輸出提示性信息(表頭)

# awk -F ":" 'BEGIN{print "1111","2222"} {print $1,$3} ' yunjisuan.txt

 

 

# awk -F ":" 'BEGIN{print "1111","2222"} {print $1,$3} END{print "asdf","asdfg"}' yunjisuan.txt

 

 

(3)使用BEGIN 模塊的特殊性質,進行一些測試(計算)

 

計算數值

# awk 'BEGIN{print 10/3}'

 

賦值變量

# awk 'BEGIN{a=1;b=2;print a,b,a+b}'

  

 

awk中字母會被認為是變量,給一個變量賦值字母(字符串),用雙引號

# awk 'BEGIN{abcd=123456;a=abcd;print a}'

123456

 

# awk 'BEGIN{a="abcd";print a}'

abcd

 

表示ab次方

# awk ‘BEGIN{a=2;b=3;print a**b}’

 

查看/etc/services空行個數

 方法一:

# grep -c “^$” /etc/services   

 

方法二:

# awk ‘/^$/ {i=i+1} END{print i}’ /etc/services

 其中,i=i+1 等同於i++

 

查看test文件一共有多少行 

# awk ‘{i++}END{print i}’ test

 

 

test文件每行的值之和

# awk ‘{i=i+$0}END{print i}’ test

 

 

求 test文件每行的值之積(BEGIN初始變量設定位置)

# awk ‘BEGIN{i=1}{i=i*$1}END{print i}’ test

 

 

awk數組

用一個變量表示多組數據,通常優先考慮數組,eg:變量名[數字]=不同的值

awk數組結構

arrayname[string]=value

arrayname為數組名

string為元素名

value為值

 

循環語句

for(變量1 in 變量2) 表示變量1在變量2 中取值,變量1被變量2循環賦值

 

統計域名訪問次數

(1)取出域名

(2)將域名去重

(3)統計次數

 

方法一:

# awk -F “/+” ‘{print $2}’ yuming | sort uniq -c

 

方法二:

# awk -F "[ /]+" '{h[$2]++}END{for(i in h)print i,h[i]}' yuming

 

 

統計域名訪問次數並累計流量

(1)取出域名

(2)將域名去重

(3)統計流量大小

#  awk -F "[ /]+" '{h[$2]=h[$2]+$4}END{for(i in h)print i,h[i]}' yuming

 

 

第一列字母去重,並求和

# awk ‘{h[$1]+$2}END{for(i in h)print i,h[i]}’ test

  

 

WEB服務器日志文件

access.www.log

(企業應用) 分析圖片服務日志,把日志(每個圖片訪問次數*圖片大小的總和)排行,取top10,也就是計算每個url的總訪問大小

(在Web服務器日志文件中查看哪個IP地址(用戶)瀏覽本機次數,使用流量最多)

思路:用awk過濾出出現的IP地址,去重IP地址,統計其使用流量,並排序

說明:本題生產環境應用:這個功能可以用於IDC網站流量帶寬很高,然后通過分析服務器日志哪些元素占用流量過大,進而進行優化或裁剪該圖片,壓縮js等措施。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM