awk使用和詳解

awk是一個強大的文本分析工具,相對於grep的查找,sed的編輯,awk在其對數據分析並生成報告時,顯得尤其強大。簡單來講awk就是把文件逐行的讀入,以空格爲默認分隔符將每行切片,切開的部分再進行各類分析處理。css

awk有3個不一樣版本: awk、nawk和gawk,未做特別說明,通常指gawk,gawk 是 AWK 的 GNU 版本。linux

awk其名稱得自於它的創始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首個字母。實際上 AWK 的確擁有本身的語言: AWK 程序設計語言 , 三位建立者已將它正式定義爲「樣式掃描和處理語言」。它容許您建立簡短的程序,這些程序讀取輸入文件、爲數據排序、處理數據、對輸入執行計算以及生成報表,還有無數其餘的功能。shell

awk是一個強大的文本分析工具,相對於grep的查找,sed的編輯,awk在其對數據分析並生成報告時,顯得尤其強大。簡單來講awk就是把文件逐行的讀入,以空格爲默認分隔符將每行切片,切開的部分再進行各類分析處理。express

awk有3個不一樣版本號: awk、nawk和gawk,未做特別說明,通常指gawk。編程

awk程序的報告生成能力通常用來從大文本文件裏提取數據元素並將它們格式化成可讀的報告。最完美的樣例是格式化日誌文件。ubuntu

awk的用法

awk 'BEGIN{ commands } pattern{ commands } END{ commands }'

第一步:運行BEGIN{ commands }語句塊中的語句。vim

第二步:從文件或標準輸入(stdin)讀取一行。而後運行pattern{ commands }語句塊,它逐行掃描文件,從第一行到最後一行反覆這個過程。直到文件全部被讀取完成。數組

第三步:當讀至輸入流末尾時。運行END{ commands }語句塊。tomcat

BEGIN語句塊在awk開始從輸入流中讀取行以前被運行,這是一個可選的語句塊,比方變量初始化、打印輸出表格的表頭等語句一般可以寫在BEGIN語句塊中。bash

END語句塊在awk從輸入流中讀取全然部的行以後即被運行。比方打印所有行的分析結果這類信息彙總都是在END語句塊中完畢,它也是一個可選語句塊。

pattern語句塊中的通用命令是最重要的部分,它也是可選的。假設沒有提供pattern語句塊,則默認運行{ print },即打印每一個讀取到的行。awk讀取的每一行都會運行該語句塊。

這三個部分缺乏任何一部分均可以。

內建變量

列出某個目錄的文件:

[root@localhost profile.d]# ls -lh
total 136K
-rwxr-xr-x 1 root root  766 Jul 22  2011 colorls.csh
-rwxr-xr-x 1 root root  727 Jul 22  2011 colorls.sh
-rw-r--r-- 1 root root   92 Feb 23  2012 cvs.csh
-rwxr-xr-x 1 root root   78 Feb 23  2012 cvs.sh
-rwxr-xr-x 1 root root  192 Mar 25  2009 glib2.csh
-rwxr-xr-x 1 root root  192 Mar 25  2009 glib2.sh
-rw-r--r-- 1 root root  218 Jun  6  2013 krb5-devel.csh
-rw-r--r-- 1 root root  229 Jun  6  2013 krb5-devel.sh
-rw-r--r-- 1 root root  218 Jun  6  2013 krb5-workstation.csh
-rw-r--r-- 1 root root  229 Jun  6  2013 krb5-workstation.sh
-rwxr-xr-x 1 root root 3.0K Feb 22  2012 lang.csh
-rwxr-xr-x 1 root root 3.4K Feb 22  2012 lang.sh
-rwxr-xr-x 1 root root  122 Feb 23  2012 less.csh
-rwxr-xr-x 1 root root  108 Feb 23  2012 less.sh
-rwxr-xr-x 1 root root   97 Mar  6  2011 vim.csh
-rwxr-xr-x 1 root root  293 Mar  6  2011 vim.sh
-rwxr-xr-x 1 root root  170 Jan  7  2007 which-2.sh

試一下awk的使用

ls -lh | awk '{print $1}'

在這裏awk 後面沒有BEGIN和END,跟着的是pattern,也就是每一行都會通過這個命令,在awk中$n,表示第幾列,在這裏表示打印每一行的第一列。

  • $0 當前記錄(這個變量中存放着整個行的內容)
  • $1~$n 當前記錄的第n個字段,字段間由FS分隔
  • FS 輸入字段分隔符 默認是空格或Tab
  • NF 當前記錄中的字段個數,就是有多少列
  • NR 已經讀出的記錄數,就是行號,從1開始,若是有多個文件話,這個值也是不斷累加中。
  • FNR 當前記錄數,與NR不一樣的是,這個值會是各個文件本身的行號
  • RS 輸入的記錄分隔符, 默認爲換行符
  • OFS 輸出字段分隔符, 默認也是空格
  • ORS 輸出的記錄分隔符,默認爲換行符
  • FILENAME 當前輸入文件的名字

如打印每一行的行數:

[root@localhost profile.d]# ls -lh | awk '{print NR " " $1}'
1 total
2 -rwxr-xr-x
3 -rwxr-xr-x
4 -rw-r--r--
5 -rwxr-xr-x
6 -rwxr-xr-x
7 -rwxr-xr-x
8 -rw-r--r--
9 -rw-r--r--
10 -rw-r--r--
11 -rw-r--r--
12 -rwxr-xr-x
13 -rwxr-xr-x
14 -rwxr-xr-x
15 -rwxr-xr-x
16 -rwxr-xr-x
17 -rwxr-xr-x
18 -rwxr-xr-x

這樣再來看這段語句應該就很容易理解了:

root@ubuntu:~# awk  -F ':'  '{printf("filename:%10s,linenumber:%s,columns:%s,linecontent:%s\n",FILENAME,NR,NF,$0)}' /etc/passwd
filename:/etc/passwd,linenumber:1,columns:7,linecontent:root:x:0:0:root:/root:/bin/bash
filename:/etc/passwd,linenumber:2,columns:7,linecontent:daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
filename:/etc/passwd,linenumber:3,columns:7,linecontent:bin:x:2:2:bin:/bin:/usr/sbin/nologin
filename:/etc/passwd,linenumber:4,columns:7,linecontent:sys:x:3:3:sys:/dev:/usr/sbin/nologin
filename:/etc/passwd,linenumber:5,columns:7,linecontent:sync:x:4:65534:sync:/bin:/bin/sync
filename:/etc/passwd,linenumber:6,columns:7,linecontent:games:x:5:60:games:/usr/games:/usr/sbin/nologin

變量

除了awk的內置變量,awk還能夠自定義變量。

以下引入變量sum,統計py文件的大小:

root@ubuntu:~# ls -l  *.py | awk '{sum+=$5} END {print sum}'
574

語句

awk中的條件語句是從C語言中借鑑來的,見以下聲明方式:

if語句

if (expression) {
    statement;
    statement;
    ... ...
}

if (expression) {
    statement;
} else {
    statement2;
}

if (expression) {
    statement1;
} else if (expression1) {
    statement2;
} else {
    statement3;
}

循環語句

awk中的循環語句一樣借鑑於C語言,支持while、do/while、for、break、continue,這些關鍵字的語義和C語言中的語義徹底相同。

數組

由於awk中數組的下標能夠是數字和字母,數組的下標一般被稱爲關鍵字(key)。值和關鍵字都存儲在內部的一張針對key/value應用hash的表格裏。因爲hash不是順序存儲,所以在顯示數組內容時會發現,它們並非按照你預料的順序顯示出來的。數組和變量同樣,都是在使用時自動建立的,awk也一樣會自動判斷其存儲的是數字仍是字符串。通常而言,awk中的數組用來從記錄中收集信息,能夠用於計算總和、統計單詞以及跟蹤模板被匹配的次數等等。

使用數組,統計重複出現的次數:

[root@localhost cc]# cat test.txt
a 00
b 01
c 00
d 02
[root@localhost cc]# awk '{sum[$2]+=1}END{for(i in sum)print i"\t"sum[i]}' test.txt
00 2
01 1
02 1

站點日誌分析

如下使用Linux中的Awk對tomcat中日誌文件作一些分析,主要統計pv,uv等。

日誌文名稱:access_2013_05_30.log,大小57.7 MB 。

此次分析僅僅是簡單演示,因此不是太精確地處理數據。

日誌地址:http://download.csdn.net/detail/u011204847/9496357

日誌數據演示樣例:

日誌總行數:

打印的第七列數據爲日誌的URL:

分析中用到的一些知識:

  • shell中的管道|
    command 1 | command 2 #他的功能是把第一個命令command 1運行的結果做爲command 2的輸入傳給command 2

  • wc -l #統計行數

  • uniq -c #在輸出行前面加上每行在輸入文件裏出現的次數

  • uniq -u #僅顯示不反覆的行

  • sort -nr
    -n:按照數值的大小排序
    -r:以相反的順序來排序
    -k:按照哪一列進行排序

  • head -3 #取前三名

數據清洗:

一、第一次清洗:去除URL中以/static/開頭的URL

awk '($7 !~ /^\/static\//){print $0}' access_2013_05_30.log > clean_2013_05_30.log

去除前:

去除後:

二、第二次清洗:去除圖片、css和js

awk '($7 !~ /\.jpg|\.png|\.jpeg|\.gif|\.css|\.js/) {print $0}' clean_2013_05_30.log > clean2_201 3_05_30.log

PV

pv是指網頁訪問次數

方法:統計所有數據的總行數

數據清洗:對原始數據中的干擾數據進行過濾

awk 'BEGIN{pv=0}{pv++}END{print "pv:"pv}' clean2_2013_05_30.log > pv_2013_05_30

UV

uv指的是訪問人數。也就是獨立IP數

對ip反覆的數據進行去重,而後再統計所有行數

awk '{print $1}' clean2_2013_05_30.log |sort -n |uniq -u |wc -l > uv_2013_05_30

訪問最多的IP(前10名)

對ip反覆的數據進行去重的時候還要彙總,取前10名

awk '{print $1}' clean2_2013_05_30.log | sort -n | uniq -c |sort -nr -k 1|head -10 > top10_2013_05_30

訪問前十的URL(可以用來分析站點哪一個模塊最受歡迎)

awk '{print $7}' clean2_2013_05_30.log | sort | uniq -c |sort -nr -k 1|head -10 > top10URL_2013_ 05_30

更多教程:阿貓學編程

相關文章
相關標籤/搜索