文本處理三劍客之AWK的用法


1.awk命令簡介:
awk是一種可以處理數據、產生格式化報表的語言,功能十分強大。
awk的工作方式是讀取數據,將每一行數據視為一條記錄(record)每筆記錄以字段分隔符分成若干字段,然后輸出各個字段的值.

2.awk常用的作用格式:
awk “樣式” 文件: 把符合樣式的數據行顯示出來。
awk { 操作 } 文件: 對每一行都執行{}中的操作。
awk " 樣式 { 操作 }" 文件: 對符合樣式的數據行,執行{}中的操作.

3.用例:
awk的用法1:

awk `/La/` dataf3       #顯示含La的行。

awk的用法2:

awk -F ":" '{print $1,$2}' /etc/passwd  #以“:”為分割,顯示/etc/passwd每一行的第1和第2個字段。$1代表第1個字段,$2代表第2個字段,其他類推.

awk的用法3:

awk '/La/{ print $1,$2 }' dataf3  #將含有La關鍵字的數據行的第1及第2個字段顯示出來.默認使用空格分割.

awk的用法4:

awk -F : '/^www/{print $3,$4}' /etc/passwd  # 使用選項 -F,指定:為分隔符,賬號www的uid(第3個字段)及gid(第4個字段)顯示出來.

awk的用法5:

[root@localhost~]# awk -F : '/^r/{print $1}' /etc/passwd		#顯示以r開頭的行的第一個字段
root
rpc
rpcuser

awk的用法6:

[root@localhost~]# awk -F : '$3>=500{print $1,$3}' /etc/passwd	#找出$3這個字段的id大於等於500的行,並顯示1、3列
www 500
cacti 501
nagios 502
vsftpd 503

awk的用法7:

[root@localhost~]# awk -F : '$7~"bash"{print $1,$7}' /etc/passwd 		#匹配出$7是bash的行,如果為真則打印出來
root /bin/bash
mysql /bin/bash
www /bin/bash
cacti /bin/bash
nagios /bin/bash

awk的用法8:

[root@localhost~]# awk -F : '$7!~"bash"{print $1,$7}' /etc/passwd		#取出$7不是bash的行並打印出來
bin /sbin/nologin
daemon /sbin/nologin
adm /sbin/nologin
lp /sbin/nologin
sync /bin/sync
shutdown /sbin/shutdown

awk擴展:

實例操作:
[root@localhost]# more awk.txt

07.46.199.184 [28/Sep/2010:04:08:20] "GET /robots.txt HTTP/1.1" 200 0 "msnbot"123.125.71.19 [28/Sep/2010:04:20:11] "GET /
HTTP/1.1" 304 - "Baiduspider

NF的用法:

1. $NF 來打印最后一個字段:

[root@localhost]# awk '{print $NF}' awk.txt     
/
"Baiduspider

2. $(NF-2):表示從右向左打印每行第二個字段.  

[root@localhost]# awk '{print $(NF-2)}' awk.txt 
[28/Sep/2010:04:20:11]
304

BEGIN{}區域指示用法:

1.OFS的作用是存儲輸出字段的分隔符

[root@localhost~]# awk -F : 'BEGIN{OFS="+++"}/^www/{ print $1 , $2 , $3 , $4 ,$5 }' /etc/passwd      
www+++x+++500+++500+++

# 以 ":" 為分隔符,+++為輸出字段分隔符,將賬號www用戶的第1-5欄顯示出來.
本例中,BEGIN{}區域指示awk一開始先做初始化的操作,即設定OFS="+++".變量OFS的作用是存儲輸出字段的分隔符.接着,尋找www的賬戶行找到后,使用print印出第1至第5個字段,且彼此使用+++隔開.

2.FS也就是字段分隔符的用法:指定輸入分隔符---讀取文本時,所使用的字段分隔符.

[root@localhost]# awk '{print $2}' awk.txt | awk 'BEGIN{FS=":"}''{print $1}'
[28/Sep/2010

3.RS表示記錄分割符--輸入文本信息所使用的換行符

從tomcat日志catalina.out中截取2014-10-13日,在07:00-15:00時間段的日志記錄,並保存.

awk 'BEGIN{RS="2014-10-13"}$1>"07:00:00"&&$1<"15:50:00"{print RS,$0}' catalina.out > catalins_link.log
       FS表示操作的時候以什么為分割符
       RS表示記錄分割符(Record Separator)
       即RS表示的是awk操作最小單位的邊界,而FS是這個最小單位中分割的符號

NR :表示打印當前正在處理的輸入的行號

awk '{print NR ") " $1 " -> " $(NF-2)}' awk.txt
其中:
        print NR :表示打印當前正在處理的輸入的行號
              “ )”:表示以半括號將行號括起來.也可以換成任意的符號,如 ]、#、@、等

               $1:  表示打印出第一列的數據.

       $(NF-2): 表示從后向前打印出倒數兩列數據. 

輸出:

1) 07.46.199.184 -> 2002) 123.125.71.19 -> 304

常用操作:

取得系統內存大小:

cat /proc/meminfo | awk '/MemTotal/{ print $2 }' 

從catalina.out中截取2014-10-13日,在07:00-15:00時間段的日志記錄,並保存.

awk 'BEGIN{RS="2014-10-13"}$1>"07:00:00"&&$1<"15:50:00"{print RS,$0}' catalina.out > 11106.log

過濾出nginx日志中狀態碼不是200的請求.

cat access.log |awk '$10!="200"{print $10}'

awk '$9 !~ /200/ {print $0}' access.log 

統計訪問時間大於5mm的URL,並進行排序

awk '$NF>5 {print $0}' access_mmall.log|awk '{print $12}'|awk -F? '{print $1}'|sort|uniq -c|sort -rbg

用awk來實現奇數行和偶數行的輸出,思路很簡單,就是判斷NR變量。NR是行號,行號是2的倍數,自然是偶數行。 

要處理的文件內容如下所示:

$ cat 1.txt 
1       Jan
2       Feb
3       Mar
4       Apr
5       May
6       Jun
7       Jul
8       Aug
9       Sep
10      Oct
11      Nov
12      Dec

輸出奇數行:

不加{print}語句也能默認輸出整行,例如

$ awk NR%2 1.txt  
1       Jan
3       Mar
5       May
7       Jul
9       Sep
11      Nov

如果還不懂看這個你就懂了,用NR對2取模,當余數為1時,awk的執行模式判斷為真,就會執行默認的{print}輸出奇數行,當余數不為1時,判斷為假,不執行輸出,所以偶數行就不會輸出。

$ awk '{if(NR%2==1)print $0}' 1.txt       
1       Jan
3       Mar
5       May
7       Jul
9       Sep
11      Nov

輸出偶數行

$ awk NR%2==0 1.txt  
2       Feb
4       Apr
6       Jun
8       Aug
10      Oct
12      Dec

或者用如下方法取反,也可以去除偶數行.

$ awk '!(NR%2)' 1.txt 
2       Feb
4       Apr
6       Jun
8       Aug
10      Oct
12      Dec

 

 


免責聲明!

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



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