三劍客之awk 第1章 awk簡介 1.1 awk簡介 一種名字怪異的語言。 模式掃描和處理。處理文本流,水流。 awk不僅僅是linux系統中的一個命令,而且是一種編程語言,可以用來處理數據和生成報告。 處理的數據可以是一個或多個文件,可以是來自標準輸入,也可以通過管道獲取標準輸入,awk可以 在 ...
三劍客之awk
第1章 awk簡介
1.1 awk簡介
- 一種名字怪異的語言。
- 模式掃描和處理。處理文本流,水流。
awk不僅僅是linux系統中的一個命令,而且是一種編程語言,可以用來處理數據和生成報告。
處理的數據可以是一個或多個文件,可以是來自標準輸入,也可以通過管道獲取標準輸入,awk可以
在命令行上直接編輯命令進行操作,也可以編寫成awk程式來進行更為複雜的運用。這裡主要講解
awk命令行的運用。
學完本章你會瞭解:
- 域(欄位)與記錄
- 模式與匹配
- 基本的awk執行過程
- awk常用內置變數(預定義變數)
- awk數組(工作中比較常用)
還有一些其他awk用法:(這裡不作介紹)
- awk語法:迴圈,條件
- awk常用函數:print
- 向awk傳遞參數
- awk引用shell變數
- awk編程
1.2 awk環境簡介
[root@linux-node1 ~]# cat /etc/redhat-release
CentOS release 6.6 (Final)
[root@linux-node1 ~]# uname -r
2.6.32-504.el6.x86_64
[root@linux-node1 ~]# awk --version
GNU Awk 3.1.7
[root@linux-node1 ~]# which awk
/bin/awk
#/bin下和/sbin下的命令區別:
/bin : commands in this dir are all system installed user commands 系統的一些指令
/sbin: commands in this dir are all system installed super user commands 超級用戶指令 系統管理命令,這裡存放的是系統管理員使用的管理程式
/usr/bin: user commands for applications 後期安裝的一些軟體的運行腳本
/usr/sbin: super user commands for applications 超級用戶的一些管理程式
1.3 awk的格式
awk指令是由模式,動作,或者模式和動作的組合組成。
模式既pattern,可以類似理解成sed的模式匹配,可以由表達式組成,也可以是兩個正斜杠之間的正則表達式。比如NR=1,這就是模式,可以把他理解為一個條件。
動作即action,是由在大括弧裡面的一條或多條語句組成,語句之間用分號隔開。如awk使用格式:
圖1-1 awk命令行格式
awk處理的內容可以來自標準輸入(<),一個或多個文本文件或管道。
圖1-2 awk模式動作解釋圖
pattern既模式,也可以理解為條件,也叫找誰,你找誰?高矮,胖瘦,男女?都是條件,既模式。
action 既動作,可以理解為幹啥,找到人之後你要做什麼。
1.4 awk執行過程
在深入瞭解awk前,我們需要知道awk如何處理文件的。
示例1-1 示例文件的創建
[root@linux-node1 ~]# mkdir -p /server/files/
[root@linux-node1 ~]# head /etc/passwd > /server/files/awkfile.txt
[root@linux-node1 ~]# cat /server/files/awkfile.txt
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
[root@linux-node1 ~]# awk 'NR>=2{print $0}' /server/files/awkfile.txt
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
[root@linux-node1 ~]# awk 'NR>=2{print NR,$0}' /server/files/awkfile.txt
2 bin:x:1:1:bin:/bin:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6 sync:x:5:0:sync:/sbin:/bin/sync
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8 halt:x:7:0:halt:/sbin:/sbin/halt
9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
10 uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
awk是通過一行一行的處理文件,這條命令中包含模式部分(條件)和動作部分(動作),awk將處理模式指定的行。
小結awk執行過程:
a)awk讀入第一行內容
b)判斷符合模式中的條件(NR>=2)
l 如果匹配預設則執行對應的動作({print $0})
l 如果不匹配條件,繼續讀取下一行
c))繼續讀取下一行
d)重覆過程a-c,直到讀取到最後一行(EOF:end of file)
1.5 區域和記錄
名稱 |
含義 |
field |
域,區域,欄位 |
record |
記錄,預設一整行 |
eg:$1,$2,$3,$NF
$0: 整行,一個記錄
$ 取 引用
1.5.1 欄位(區域)
每條記錄都是由多個欄位(field)組成的,預設情況下之間的分隔符是由空白符(即空格或製表符)來分隔,並且將分隔符記錄在內置變數FS中。每行記錄的欄位數保存在awk的內置變數NF中。
圖1-4 awk區域分隔符
awk使用內置變數FS來記錄欄位分隔符的內容,可以通過BEGIN語句來更改,也可以在命令行上通過-F參數來更改,下麵通過示例來加強學習。
示例1-3 FS演示文件生成
[root@linux-node1 ~]# awk -F ":" 'NR>=2&&NR<=5{print $1,$3}' /server/files/awkfile.txt
bin 1
daemon 2
adm 3
lp 4
1.5.2記錄
awk對每個要處理的輸入數據人為都是具有格式和結構的,而不僅僅是一堆字元串。預設情況下,每一行內容都成為一條記錄,並以換行符結束。
² 預設情況 -一行==一個記錄,每行都是一個記錄。
² RS ==》 record separator 每個記錄讀入的時候的分隔符。
² NR==》 number of record 行號,記錄的數。awk當前處理著的,記錄的數。
² ORS==》 output record separate 輸出食肉的分隔符
awk使用內置變數來存放記錄分隔符,RS表示的是輸入的記錄分隔符,這個值也可以以特定的方式修改。
前面我們講到過的$0,awk使用$0來表示整條記錄。記錄分隔符\n保存在RS變數中。另外awk對每一行的記錄號都有一個內置變數NR來保存,每處理完一條記錄NR的值就會自動+1.
下麵通過示例來加強一下什麼是記錄,記錄分隔符。
示例1-5 NR記錄行號
[root@linux-node1 files]# awk '{print NR,$0}' awkfile.txt
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6 sync:x:5:0:sync:/sbin:/bin/sync
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8 halt:x:7:0:halt:/sbin:/sbin/halt
9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
10 uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
示例1-6 RS記錄分隔符
#以/為分隔符記錄一行
[root@linux-node1 files]# awk 'BEGIN{RS="/"}{print NR,$0}' awkfile.txt
1 root:x:0:0:root:
2 root:
3 bin
4 bash
bin:x:1:1:bin:
5 bin:
6 sbin
7 nologin
daemon:x:2:2:daemon:
8 sbin:
9 sbin
10 nologin
adm:x:3:4:adm:
11 var
12 adm:
13 sbin
14 nologin
lp:x:4:7:lp:
15 var
16 spool
17 lpd:
18 sbin
19 nologin
#以:為分隔符記錄一行
[root@linux-node1 files]# awk 'BEGIN{RS=":"}{print NR,$0}' awkfile.txt
1 root
2 x
3 0
4 0
5 root
6 /root
7 /bin/bash
bin
8 x
9 1
10 1
11 bin
12 /bin
13 /sbin/nologin
daemon
14 x
15 2
16 2
17 daemon
18 /sbin
19 /sbin/nologin
adm
20 x
21 3
22 4
23 adm
24 /var/adm
25 /sbin/nologin
lp
26 x
27 4
28 7
29 lp
30 /var/spool/lpd
31 /sbin/nologin
awk 眼中的文件,從頭到尾一段連續的字元串,恰巧中間有些\n(回車換行符)
示例1-7 RS為空值
#RS為空值的時候將指定行輸出為一行
[root@linux-node1 files]# awk 'BEGIN{RS=""}{print NR,$1,$2,$3}' awkfile.txt
說明:
在行首列印輸出記錄號,並列印出每一行$0的內容
企業案例1:計算文件中每個單詞的重覆數量
[root@linux-node1 files]# sed -ri.bak 's#[:/0-9]+# #g' awkfile.txt
1)單詞弄成一列(排隊)
其中 -o 表示“only-matching 精確匹配
[root@linux-node1 files]# egrep -o "[a-zA-z]+" awkfile.txt |sort| uniq -c|sort -r
5 x
5 sbin
4 nologin
4 bin
3 root
3 adm
2 var
2 lp
2 daemon
1 spool
1 lpd
1 bash
2)統計
[root@linux-node1 files]# awk 'BEGIN{RS="() | \n"}{print $0}' awkfile.txt|sort |uniq -c|sort -rn
5 x
5 sbin
4 nologin
4 bin
3 root
3 adm
2 var
2 lp
2 daemon
1 spool
1 lpd
1 bash
1
企業案例2: 統計文件中每個字母的重覆數量
記錄小結:
- 大象放冰箱分幾步?打開冰箱,把大象放進去,關閉冰箱門。
- 多用NR,NF,$數字,配合你進行調試awk命令。
- NR存放著每個記錄的號(行號)讀取新行時候會自動+1
- RS是記錄的分隔符,簡單理解就是可以指定每個記錄的結尾標誌。
- (用RS替換\n)
- RS作用就是表示一個記錄的結束。
- FS標識著每個區域的結束。
1.6 模式匹配
1.6.1 正則表達式
awk支持的正則表達式元字元
元字元 |
功能 |
示例 |
解釋 |
^ |
字元串開頭 |
/^cool/ |
匹配所有以cool開頭的字元串 |
$ |
字元串結尾 |
/cool$/ |
匹配所有以cool結尾的字元串 |
. |
匹配任意單個字元 (包括回車符) |
/c..l/ |
匹配字母c,然後兩個任意字元,再以l結尾的行,比如ckk1,c@#1等 |
* |
匹配0個或多個前導字元 |
/a*cool/ |
匹配0個或多個a之後緊跟著cool的行,比如cool,aaacool |
+ |
重覆一次或一次以上 |
/a+b/ |
匹配一個或多個a加b的行 |
? |
匹配0個或一個前導字元 |
/a?b/ |
匹配b或ab的行 |
[] |
匹配指定字元組內的任一個字元 |
/^[abc]/ |
匹配以字母a或b或c開頭的行 |
[^] |
匹配不在指定字元組 |
/^[^abc]/ |
匹配不以字母a或b或c開頭的行 |
x{m} |
x重覆m次 x重覆至少m次 x重覆至少m次,但不超過n次 需要指定參數:--posix或者--re-interval |
/(cool){5} |
需要註意的一點是,cool加括弧或不加括弧的區別,x可以使字元串也可以只是一個字元,所有/cool\{5\}/表示匹配coo再加上5個l,即coolllll, ^(cool\){2,\}則表示匹配coolcool, coolcoolcool等 |
x{m,} |
/(cool){2,}/ |
||
|
/(cool){5,6}/ |
正則表達式的運用,預設是在行內查找匹配的字元串,若有匹配則執行action操作,但是有時候僅需要固定的列來匹配指定的正則表達式,比如:$3這一列查找匹配tom的行,這樣就需要另外兩個匹配操作符:
~:用於對記錄或欄位的表達式進行(匹配)
!~:用於表達與~想法的意思。(不匹配)
#匹配 第五列以l或者a開頭的所有行 ,這裡(l|a) 可以換成[al]
[root@linux-node1 files]# awk '$3~/^(l|a)/{print $0}' awkfile.txt
adm x adm var adm sbin nologin
lp x lp var spool lpd sbin nologin
#取eth0 ip
[root@linux-node1 files]# ifconfig eth0| awk -F "[ :]+" 'NR==2{print $4}'
10.0.0.7
[root@linux-node1 files]# ifconfig eth0| awk -F "addr:| Bcast:" 'NR==2{print $2}'
10.0.0.7
[root@linux-node1 files]# echo "-----=====1#######2"
-----=====1#######2
[root@linux-node1 files]# echo "-----=====1#######2"|grep "[-=#]"
-----=====1#######2
[root@linux-node1 files]# echo "-----=====1#######2"|grep -o "[-=#]"
-
-
-
-
-
=
=
=
=
=
#
#
#
#
#
#
#
[root@linux-node1 files]# echo "-----=====1#######2"|egrep -o "[-=#]+"
-----=====
#######
#匹配o出現一次或者兩次的行列印第一列和最後一列
[root@linux-node1 files]# awk --posix '$1~/o{1,2}/{print NR,$1,$NF}' awkfile.txt
1 root bash
3 daemon nologin
1.6.2比較表達式
示例1-18
[root@linux-node1 files]# awk 'NR>=2&&NR<=5{print NR,$0}' awkfile.txt
2 bin x bin bin sbin nologin
3 daemon x daemon sbin sbin nologin
4 adm x adm var adm sbin nologin
5 lp x lp var spool lpd sbin nologin
1.6.3範圍模式
awk ‘/start pos/,/end pos/{print $0} ‘ test.txt
awk ‘/start pos/,NR==XXX{print $0}’ passwd.oldboy
範圍模式的時候,範圍條件的時候,表達式必須匹配一行,
[root@linux-node1 files]# awk 'NR==2,NR==5{print NR,$1,$3}' awkfile.txt
2 bin bin
3 daemon daemon
4 adm adm
5 lp lp
[root@linux-node1 files]# awk 'NR==2,NR==5{print NR,$0}' awkfile.txt
2 bin x bin bin sbin nologin
3 daemon x daemon sbin sbin nologin
4 adm x adm var adm sbin nologin
5 lp x lp var spool lpd sbin nologin
[root@linux-node1 files]# awk 'NR==2,NR<=5{print NR,$0}' awkfile.txt
2 bin x bin bin sbin nologin
1.6.4企業案例:取出常用服務埠號
ftp http https mysql ssh 埠號 /etc/services 文件
[root@linux-node1 files]# awk -F "[ /]+" '$1~/ftp|https|mysql|ssh)$/{print $1,$2}' /etc/services|uniq
小結:
- 模式===》條件
- 正則表達式
- 條件表達式(NR>=2 NR==2)
- 範圍表達式
- (NR==2,NR==5)
- /正則表達式-開始/,/正則結束/
- $1~/正則表達式-開始/,$3~/正則結束/ 行,記錄。
- 區域:FS刀分隔的,FS區域分隔符
- 記錄:RS刀分隔的,RS記錄分隔符
- FS===>NF 區域的數量
- RS===>NR 記錄號,隨著記錄的增加NR自動+1
1.7 awk結構的回顧
1.7.1 BEGIN模塊
BEGIN模式之前我們有在示例中提到,自定義變數,給內容變數賦值等,都是用過。需要註意的是BEGIN模式後面要接跟一個action操作塊,包含在大括弧內。awk必須在對輸入文件進行任何處理前先執行BEGIN定義的action操作塊。我們可以不要任何輸入文件,就可以對BEGIN模塊進行測試,因為awk需要先執行完BEGIN模式,菜對輸入文件做處理。BEGIN模式常常被用來修改內置變數ORS,RS,FS,OFS等的值。
示例1-25
[root@linux-node1 files]# awk 'BEGIN{print "this is begin!\nand thiscommand donnot have file"}'
this is begin!
and thiscommand donnot have file
說明:
沒有文件awk依舊可以處理BEGIN模式下的操作塊。
1.7.2 END模塊
END 在awk讀取完所有的文件的時候
awk編程思想:
1.先處理,最後再END模塊輸出。
與BEGIN模式相對於的END模式,格式一樣,但是END模式僅在awk處理完所有輸入行後才進行處理。並且在END模式下awk不匹配任何輸入行。
1.7.3 總結awk執行過程
1.讀入一行
2.判斷是否是需要的行 條件$3>15 滿足大於15 執行action :print
3.不滿足條件重覆1,2步驟
1.7.4 企業案例3:統計文件裡面的空行數量
[root@linux-node1 files]# grep -c "^$" /etc/services
16
[root@linux-node1 files]# awk '/^$/{a=a+1;print a}' /etc/services
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@linux-node1 files]# awk '/^$/{a=a+1}END{print a}' /etc/services
16
head -20 /etc/passwd >awkfile2.txt
面試題:awkfile2.txt 裡面 以:為分隔符,區域3大於15行,一共有多少個?
[root@linux-node1 files]# awk -F ":" '$3>15{print $0}' awkfile2.txt
nobody:x:99:99:Nobody:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin
vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/cache/rpcbind:/sbin/nologin
rtkit:x:499:497:RealtimeKit:/proc:/sbin/nologin
#計算一次,輸出一次
[root@linux-node1 files]# awk -F ":" '$3>15{a=a+1;print a}' awkfile2.txt
1
2
3
4
5
6
#處理完文件以後再輸出a 這裡a=a+1 可以用a++代替
[root@linux-node1 files]# awk -F ":" '$3>15{a=a+1;}END{print a}' awkfile2.txt
6
企業面試題5:1+.....+100 1加到100的值,用awk實現
root@linux-node1 files]# seq 100 > test.txt
[root@linux-node1 files]# cat test.txt |awk '{a+=$0}END{print a}'
5050
[[root@linux-node1 files]# awk 'a=a+$0;END{print a}' test.txt |sed -n '$p'
5050
1.7.4 企業案例4:
找出環境變數$PATH中,所有隻有三個任意字元的命令,例如tee,並將他們重定向到command.txt中,要求一行顯示1個,併在文件尾部統計他們的個數.
[root@linux-node1 files]# find $(echo $PATH|tr ":" " ") -type f -name "???"| awk '{a++}END{print "result:"a}'
find: `/root/bin': No such file or directory
result:75
通配符:用來匹配文件名的。{}字元序列
正則表達:字元串
1.7.5 總結awk執行過程
[root@linux-node1 files]# awk -F ":" 'BEGIN{print FS}'
:
先執行命令再執行BEGIN模塊
思想:
- awk核心思想就是現處理,然後END模塊輸出。(累加(a++;a+=$0),awk數組)
- BEGIN模塊用於awk內置變數FS,RS的賦值,列印標題頭的信息,(excel表格裡面標題行)
- END模塊用來最後輸出,統計信息,awk數組信息。
- 區域,記錄
- BEGIN和END模塊只能有一個。不能BEGIN{}BEGIN{}或者END{}END{}
- 找誰幹啥模塊,可以是多個。
NR=2{print $1}NR=5{print $0}
1.8awk內置變數(預定義變數)
變數名 |
屬性 |
$0 |
當前記錄 |
$1-$n |
當前記錄的第n個欄位,欄位間由FS分隔 |
FS |
輸入欄位分隔符 預設是空格 |
NF |
當前記錄中的欄位個數。就是有多少列 |
NR |
已經讀出的記錄數,就是行號,從1開始 |
RS |
輸入的記錄分隔符預設為換行符 |
OFS |
輸出欄位分隔符 預設也是空格 |
ORS |
輸出的記錄分隔符,預設為 |
FNR |
當前文件的讀入記錄號 |
1.9 awk數組
示例1-9數組演示
array[b]=”aaa”:array.....
1.9.1企業面試題1
處理以下文件內容,將功能變數名稱取出並根據功能變數名稱進行計數排序處理(去重):(百度和sohu面試題)
[root@linux-node1 files]# cat awkfile3.txt
http://www.etiantian.org/index.html
http://www.etiantian.org/1.html
http://post.etiantian.org/index.html
http://mp3.etiantian.org/index.html
http://www.etiantian.org/3.html
http://post.etiantian.org/2.html
[root@linux-node1 files]# awk -F "/" '{array[$3]++}END{for(key in array) print key,array[key]}' awkfile3.txt
mp3.etiantian.org 1
post.etiantian.org 2
www.etiantian.org 3
[root@linux-node1 files]# awk -F "/+" '{array[$2]++}END{for(key in array)print key,array[key]}' awkfile3.txt
mp3.etiantian.org 1
post.etiantian.org 2
www.etiantian.org 3
小結:
- awk數組去重
- 選好分隔符 -F “/”
- 選好處理的區域,print $1,$3,$2
- array[$3]++
- 先處理,最後END模塊輸出
- 輸出awk數組我們使用for(key in array)
- ===>for ()迴圈
- key in array 手去框里,抓蘋果。
- key 就是蘋果名字(數組元素的名字)
- array數組名(框的名字)
- 列印輸出print key,array[key]
1.9.2 企業案例2統計每個IP的訪問量
access_awk.log
1.10 awk相關英語總結
名稱 |
含義 |
filed |
域,區域,欄位 |
record |
記錄,預設一整行 |
Filed Separator |
FS:區域分隔符,表示一個區域的結束,欄位,域 |
Number of Filed |
NF:每一個記錄中區域的數量 |
Record Separator |
RS:記錄分隔符,表示每個記錄的結束 |
output filed separator |
OFS |
output Record Separator |
ORS |
awk當前處理的文件的記錄號 |
FNR |
[root@linux-node1 files]# seq 20 30 >20-30.txt
[root@linux-node1 files]# seq 50 60 >50-60.txt
[root@linux-node1 files]# awk '{print FNR,NR,$0}' 20-30.txt 50-60.txt
1 1 20
2 2 21
3 3 22
4 4 23
5 5 24
6 6 25
7 7 26
8 8 27
9 9 28
10 10 29
11 11 30
1 12 50
2 13 51
3 14 52
4 15 53
5 16 54
6 17 55
7 18 56
8 19 57
9 20 58
10 21 59
11 22 60
第2章awk總結:
2.1.找誰幹啥模塊
2.2awk執行過程-完全
BEGIN模塊輸出一些提示性文字。awk內置變數FS,RS,ORS,OFS。
END 模塊輸出一些提示性文字,顯示最後的結果,計算空行,awk數組,去蘋果的過程把蘋果展示處理。
awk裡面的普通變數不用初始化。
awk先處理,一行一行的處理,然後END模塊輸出。
- 域與記錄
FS指定各種各樣的刀(正則表示),RS正則表達
- 模式匹配===》條件 如何找人。
正則表達式
^字元串開頭
$字元串結尾
$3~/^http$/
--posix或 --re-interval
r{n,m}
匹配精確,模糊
NR==1
NR>=2
模式預設匹配 一行$0
$3~/^r/
awk ‘$3~/[4-6]/{print $0}’ passwd.txt
範圍匹配
NR=2,NR=5 ==>2,5p
/start 位置/,/結束位置/
- 遇到正則表達式/ /
- $3~/reg/
- > = <
- NR==2,NR=5 /start位置/,/結束位置/
- awk數組
數組 ==>元素
一個筐==》蘋果
題目來源:
http://edu.51cto.com/course/course_id-4319.html
3. 考試題
考試題1:處理以下文件內容,將功能變數名稱取出並根據功能變數名稱進行計數排序處理:(百度和sohu面試題)
oldboy.log
http://www.etiantian.org/index.html
http://www.etiantian.org/1.html
http://post.etiantian.org/index.html
http://mp3.etiantian.org/index.html
http://www.etiantian.org/3.html
http://post.etiantian.org/2.html
答案 (4種)
#這裡的
root@linux-node1 files]# awk -F "/" '{array[$3]++}END{for(key in array) print key,array[key]}' awkfile3.txt
[root@linux-node1 files]# awk -F "/+" '{array[$2]++}END{for(key in array)print key,array[key]}' awkfile3.txt
[root@linux-node1 files]# cut -d / -f3 awkfile3.txt|sort|uniq -c|sort -nrk2
[root@linux-node1 files]# sort -t / -rk3 awkfile3.txt|awk -F / '{print $3}'|uniq -c
考試題2:統計企業工作中高併發web伺服器不同網路連接狀態對應的數量
[root@linux-node1 files]# netstat -ant|awk 'NR>=3{array[$6]++}END{for(key in array)print key,array[key]}'
TIME_WAIT 134
SYN_SENT 1
ESTABLISHED 5
LISTEN 10
[root@linux-node1 files]# netstat -ant|awk '{print $6}'|uniq -c|sort -nr
138 TIME_WAIT
7 LISTEN
5 ESTABLISHED
3 LISTEN
1 Foreign
1 established)
考試題3.分析圖片服務日誌,把日誌(每個圖片訪問次數*圖片大小的總和)排行,取top10,也就是計算每個url的總訪問大小【附加題:加分題】。
說明:本題生產環境應用:這個功能可以用於IDC網站流量帶寬很高,然後通過分析伺服器日誌哪些元素占用流量過大,進而進行優化或裁剪該圖片,壓縮js等措施。
本題需要輸出三個指標: 【訪問次數】 【訪問次數*單個文件大小】 【文件名(可以帶URL)】
測試數據
59.33.26.105 - - [08/Dec/2010:15:43:56 +0800] "GET /static/images/photos/2.jpg HTTP/1.1" 200 11299 "http://oldboy.blog.51cto.com/static/web/column/17/index.shtml?courseId=43" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)"
59.33.26.105 - - [08/Dec/2010:15:43:56 +0800] "GET /static/images/photos/2.jpg HTTP/1.1" 200 11299 "http://oldboy.blog.51cto.com/static/web/column/17/index.shtml?courseId=43" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)"
59.33.26.105 - - [08/Dec/2010:15:44:02 +0800] "GET /static/flex/vedioLoading.swf HTTP/1.1" 200 3583 "http://oldboy.blog.51cto.com/static/flex/AdobeVideoPlayer.swf?width=590&height=328&url=/[[DYNAMIC]]/2" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)"
124.115.4.18 - - [08/Dec/2010:15:44:15 +0800] "GET /?= HTTP/1.1" 200 46232 "-" "-"
124.115.4.18 - - [08/Dec/2010:15:44:25 +0800] "GET /static/js/web_js.js HTTP/1.1" 200 4460 "-" "-"
124.115.4.18 - - [08/Dec/2010:15:44:25 +0800] "GET /static/js/jquery.lazyload.js HTTP/1.1" 200 1627 "-" "-"
答案:
[root@linux-node1 files]# awk 'BEGIN{print"URL:""\t""num:\t""total_size:"}{a[$7]++;b[$7]=$10}END{for(key in a)print key"\t"a[key]"\t"a[key]*b[key]}' images.log
URL: num: total_size:
/?= 1 46232
/static/js/web_js.js 1 4460
/static/images/photos/2.jpg 2 22598
/static/flex/vedioLoading.swf 1 3583
/static/js/jquery.lazyload.js 1 1627
理解透上述問題並搞定後,你將可以輕鬆搞定如下擴展的考試題:
擴展考試題1:
4.假如現在有個文本,格式如下:
a 1
b 3
c 2
d 7
b 5
a 3
g 2
f 6
d 9
即左邊是隨機字母,右邊是隨機數字,要求寫個腳本使其輸出格式為:
a 4
b 8
c 2
d 16
f 6
g 2
即將相同的字母後面的數字加在一起,按字母的順序輸出。
答案:
答案
[root@linux-node1 files]# awk '{if(! a[$1]++)b[++n]=$1;c[$1]+=$2}END{for(i=1;i<=n;i++)print b[i],c[b[i]]}' a.txt
a 4
b 8
c 2
d 16
g 2
f 6
擴展考試題2:用shell處理以下內容
1、按單詞出現頻率降序排序!
2、按字母出現頻率降序排序!
the squid project provides a number of resources to assist users design,implement and support squid installations. Please browse the documentation and support sections for more infomation
1.答案
[root@linux-node1 files]# sed -r 's#,| #\n#g' b.txt|awk '{array[$0]++}END{for(key in array) print array[key],key}'|sort -r
2 the
2 support
2 squid
2 and
1 users
1 to
1 sections
1 resources
1 provides
1 project
1 of
1 number
1 more
1 installations.
1 infomation
1 implement
1 for
1 documentation
1 design
1 browse
1 assist
1 a
1 Please
1
2.答案
[root@linux-node1 files]# sed 's#[a-zA-Z]#& #g' b.txt|awk 'BEGIN{RS=" "}{arr[$1]++}END{for(i in arr) print arr[i],i}'|sort -nr
25
19 s
17 e
16 o
14 t
12 n
11 r
11 i
9 a
8 u
7 p
7 d
6 m
4 l
4 c
3 f
2 q
2 h
2 b
1 w
1 v
1 j
1 g
1 P
1 .
1 ,i