GAWK:報告生成器太示,格式化文本輸出
awk [options] ‘program’ var=value file…
awk [options] -f programfile var=value file…
awk [options] 'BEGIN{ action;… } pattern{ action;… } END{ action;… }' file ...
awk程序組成部分:
BEGIN語句塊、能夠使用模式匹配的通用語句塊香浩、END語句塊
選項:
-F:指明輸入時用到的字段分割符类缤;
-v var=value:自定義變量
-f:指定awk腳本,從腳本中讀取program
基本格式:
awk [options] 'program' file...
program:pattern{action statements;...}? 通常在單引號或雙引號中弃衍;
pattern與action:
pattern部分決定動作語句何時觸發(fā)及事件
BEGIN:模式匹配之前要執(zhí)行的動作
END:模式匹配結束之后要執(zhí)行的動作
action statements對數據進行處理呀非,放在{}內指明;
print? $0,$!.......$(NF-1)........$NF(最后一列)
分隔符,域,記錄:
awk執(zhí)行時镜盯,由分隔符分隔的字段(域)標記$1,$2...$n稱為域標識岸裙。$0為所有域。
文件的每一行稱為記錄速缆;
省略action降允,則默認執(zhí)行print $0的操作;
awk的工作原理:
1)艺糜、執(zhí)行BEGIN{action;...}語句塊中的語句剧董;
2)、從文件或標準輸入(stdin)讀取一行破停,然后執(zhí)行pattern{action;...}語句塊翅楼,它會逐行掃描文件,從第一行到最后一行重復這個過程真慢,知道文件被全部讀取完畢毅臊;
3)、當讀至輸入流末尾時黑界,執(zhí)行END{action;...}語句塊
BEGIN語句塊:在awk開始從輸入流中讀取行之前被執(zhí)行管嬉,這是一個可選的語句塊,比如變量初始化朗鸠、打印輸出表格的表頭等語句通常 可以寫在BEGIN語句塊中蚯撩。
END語句塊:在awk從輸入流中讀取完所有的行之后即被執(zhí)行,比如 打印所有行的分析結果這類信息匯總都是在END語句塊中完成它也是一個可選語句塊
pattern語句塊中的通用命令是最重要的部分烛占,也是可選的胎挎。如果 沒有提供pattern語句塊,則默認執(zhí)行{ print }忆家,即打印每一個讀取到的行犹菇,awk讀取的每一行都會執(zhí)行該語句塊? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
print格式:print item1,item2,...
1)、逗號為分隔符弦赖;
2)、輸出的個item可以是字符串浦辨,也可以是當前記錄的字段蹬竖、變量或awk的表達式沼沈;
3)、如省略item币厕,相當于print $0列另;
awk '{print "hello,awk"}'
awk –F: '{print}' /etc/passwd # -F指定分割符為? :冒號
awk –F: '{print “wang”}' /etc/passwd
awk –F: '{print $1}' /etc/passwd
awk –F: '{print $0}' /etc/passwd
awk –F: '{print $1”\t”$3}' /etc/passwd
tail –3 /etc/fstab |awk '{print $2,$4}'
變量:
FS:輸入字段分隔符,默認為空白字符旦装;
1
awk -v FS=':' '{print $1,FS,$3}' file
OFS:輸出字段分隔符页衙,默認為空白字符;指定輸出時的分隔符是什么阴绢,一般可以進行分隔符號替換店乐,類似下面的ORS的作用
awk -v FS=':' -v OFS=':' '{print $1,$2,$3}' file
[root@mysql-141 ~]# awk -v FS=':' -v OFS='#' '{print $1,$2,$3}' /etc/passwd
root#x#0
bin#x#1
daemon#x#2
adm#x#3
RS:輸入記錄分隔符,指定輸入時的換行符呻袭,原換行符仍有效眨八;
awk -v RS=' ' '{print}' file
ORS:輸出記錄分隔符,輸出時用指定符號代替換行符左电;
awk -v RS=' ' -v ORS='$$$' '{print}' file
NF:字段數量
awk -F: '{print NF}' file
awk -F: '{print $(NF-1)}' file
# 顯示文件的第一列廉侧,第三列,倒數第二列和最后一列
[root@mysql-141 ~]# awk -F : '{print $1,$2,$(NF-1),$NF}' /etc/passwd
root x /root /bin/bash
bin x /bin /sbin/nologin
daemon x /sbin /sbin/nologin
adm x /var/adm /sbin/nologin
NR:行號
awk -F: '{print NR,$1}' file?? # 與FNR類似
awk END'{print NR}' file
[root@mysql-141 ~]# awk END'{print NR}' /etc/passwd #將文件內容讀取完成之后篓足,統(tǒng)計行數
26
awk 'NR==2,NR==6{print NR,$0}}' file #顯示文件2-6行
FNR:各文件的行號分別計數段誊;
awk -F: '{print FNR,$1}' file1 file2...
[root@mysql-141 ~]# awk -F: '{print FNR,$1}' /etc/passwd
1 root
2 bin
3 daemon
4 adm
5 lp
6 sync
7 shutdown
8 halt
FILENAME:當前文件名;文件內容有多少行栈拖,awk就會輸出多少行
awk '{print FILENAME}' FILE1 FILE2...
[root@mysql-141 ~]# awk '{print FILENAME}' /etc/passwd |wc -l
26
[root@mysql-141 ~]# wc -l /etc/passwd
26 /etc/passwd
ARGV:數組连舍,保存的是命令行所給定的各參數;
awk 'BEGIN {print ARGV[0]}' /etc/fstab /etc/inittab
awk 'BEGIN {print ARGV[1]}' /etc/fstab /etc/inittab
[root@mysql-141 ~]# awk 'BEGIN {print ARGV[1]}' /etc/fstab /etc/inittab # 相當于shell里面的$1 $2 $3 的概念
/etc/fstab
[root@mysql-141 ~]# awk 'BEGIN {print ARGV[2]}' /etc/fstab /etc/inittab
/etc/inittab
[root@mysql-141 ~]# awk 'BEGIN {print ARGV[0]}' /etc/fstab /etc/inittab
awk
[root@mysql-141 ~]# awk 'BEGIN {print ARGV[3]}' /etc/fstab /etc/inittab
算術操作符:
x+y x-y x*y x/y x^y x%y
-x:轉換為負數辱魁;
+x:轉換為數值烟瞧,變量通過+連接運算,自動強制將字符串轉為整形染簇,非數字變成0参滴,發(fā)現第一個非數字字符,后面的自動忽略锻弓;
字符串操作符:沒有符號的操作符砾赔,字符串連接
賦值操作符:
=??? +=??? -=???? *=????? /=????? %=???? ^=????? ++????? --
比較操作符:
==?? !=?? >??? >=??? <??? <=
模式匹配符:
~:左邊的內容是否被右邊的模式包含匹配
?!~:是否不匹配;
1
[root@mysql-141 ~]# awk -F: '$0 ~ /root/{print $1}' /etc/passwd? # 以:為分隔符青灼,匹配全部內容包含root的行暴心,打印第一列
root
operator
[root@mysql-141 ~]# awk '$0 ~ "^root"' /etc/passwd # 匹配所有內容,期初以root開頭的行
root:x:0:0:root:/root:/bin/bash
[root@mysql-141 ~]# awk -F: '$3==0' /etc/passwd # 匹配以冒號為分隔符杂拨,第三列是0的行
root:x:0:0:root:/root:/bin/bash
cat >>/tmp/reg.txt<<EOF
Zhang??? Dandan??????? 41117397??? :250:100:175
Zhang??? Xiaoyu??????? 390320151??? :155:90:201
Meng??? Feixue??????? 80042789??? :250:60:50
Wu??? Waiwai??????? 70271111??? :250:80:75
Liu??? Bingbing??? 41117483??? :250:100:175
Wang??? Xiaoai??????? 3515064655??? :50:95:135
Zi??? Gege??????? 1986787350??? :250:168:200
Li??? Youjiu??????? 918391635??? :175:75:300
Lao??? Nanhai??????? 918391635??? :250:100:175
EOF
操作符:
與&&
?或||
?非专普!
示例:
[root@mysql-141 ~]# awk -F : '$3>=0 && $3<=1000 {print $1}' /etc/passwd
root
bin
daemon
adm
lp
[root@mysql-141 ~]# awk -F : '$3==0 || $3>=1000 {print $1}' /etc/passwd
root
[root@mysql-141 ~]# awk -F : '!($3==0) {print $1}' /etc/passwd
bin
daemon
adm
lp
[root@mysql-141 ~]# awk -F : '!($3>=500) {print $3}' /etc/passwd
0
1
2
3
4
5
6
awk PATTERN:
1)、如果未指定:空模式弹沽,匹配每一行檀夹;
2)筋粗、/regular expression/:僅處理能夠被模式匹配到的行,需要用//括起來炸渡;
awk '/^UUID/{print $1}' /etc/passwd
awk '!/^UUID/{print $1}' /etc/passwd
3)娜亿、relational expression:關系表達式,結果未"真"才會被處理蚌堵;
真:結果為非0值买决,非空字符串;
假:結果為空字符串或0值吼畏;
awk -F : 'i=1;j=1{print i,j}' /etc/passwd
awk '!0' /etc/passwd ; awk '!1' /etc/passwd
awk –F : '$3>=1000{print $1,$3}' /etc/passwd
awk -F : '$3<1000{print $1,$3}' /etc/passwd
[root@mysql-141 ~]# awk -F : '$NF=="/bin/bash"{print $1,$NF}' /etc/passwd
root /bin/bash
lipeng /bin/bash
[root@mysql-141 ~]# awk -F : '$NF ~ /nologin$/{print $1,$NF}' /etc/passwd
bin /sbin/nologin
daemon /sbin/nologin
adm /sbin/nologin
lp /sbin/nologin
mail /sbin/nologin
uucp /sbin/nologin
4)督赤、line ranges:行范圍:
startline,endine:/pat1/,/pat2/ 不支持直接給出數字格式:
[root@mysql-141 ~]# awk -F: '/^root\>/,/^nobody\>/{print $1}' /etc/passwd
root
bin
daemon
adm
lp
nobody
[root@mysql-141 ~]# awk -F: '(NR>=10&&NR<=20){print NR,$1}' /etc/passwd
10 uucp
11 operator
12 games
13 gopher
14 ftp
awk數組概念:
預備知識: 了解兩種awk運算方法
1) 累加運算 1+1+1
i=i+1 i初始狀態(tài)為0
i++
eg: 統(tǒng)計/etc/services文件中空行數量
第一個里程: 找出文件中空行信息
awk '/^$/' /etc/services
第二個里程: 統(tǒng)計空行數量
awk '/^$/{i=i+1;print i}' /etc/services
PS: awk中所有字符串信息都會識別為變量名稱信息, 調取變量是不需要加上$符號
awk中想顯示指定字符串信息, 需要在字符串外面加上雙引號信息
[root@oldgirl ~]# awk '/^$/{i=i+1;print i}' /etc/services
1??????? #? i=i+1 i=0 i=0+1 --> i=1
2 #? i=i+1 i=1 i=1+1 --> i=2
3 #? i=2 i=2+1 --> i=3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@oldgirl ~]# awk '/^$/{i=i+1}END{print i}' /etc/services # 將文件內容加載完之后,做出統(tǒng)計
16
2) 求和運算 10+20+5
i=i+$n i的初始狀態(tài)為0?? $n取第幾列數值信息
[root@oldgirl ~]# seq 10|awk '{i=i+$0;print i}'
1 i=i+$0 i=0 $0=1 i=0+1 -- 1 1
2 i=i+$0 i=1 $0=2 i=1+2 -- 3 3
3 i=i+$0 i=3 $0=3 i=3+3 -- 6 6
4 10
5 15
6 21
7 28
8 36
9 45
10 55
[root@mysql-141 ~]# seq 10|awk '{i=i+$0;print i}'
1
3
6
10
15
21
28
36
45
55
3). 數組的表現形式????????
數組中的括號里面的內容
hotel[元素01]=xiaolizi1? --- 調用print xiaolizi1[元素01]--- xiaolizi1
hotel[元素02]=xiaolizi2 --- 調用print xiaolizi2[元素02]--- xiaolizi2
數組統(tǒng)計命令組成說明:
1) 找出要統(tǒng)計的信息
$1
2) 把指定要統(tǒng)計信息作為數組的元素
h[$1]
3) 利用統(tǒng)計運算公式,進行運算
h[$1]=h[$1]+1 --- i=i+1
4) 顯示運算的結果信息
a 只看某一個元素的結果信息
awk '{h[$1]=h[$1]+1}END{print h["101.226.61.184"]}' access.log
5
b 要看全部元素的結果信息
awk '{h[$1]=h[$1]+1}END{print h["101.226.61.184"],h["114.94.29.165"]}' access.log
# 精簡后命令
awk '{h[$1]++}END{for(name in h)print name,h[name]}' access.log
for name in 101.226.61.184 114.94.29.165
print h[$name]
==>
for(name in h) --- > echo name=h=第一個元素信息
echo name=h=第二個元素信息????????
說明: 循環(huán)中讀取數組名稱==讀取每一個元素名稱信息
cat >>url.txt<<EOF
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
EOF
awk '{h[$1]++}END{for(name in h)print name,h[name]}' access.log
[root@mysql-141 ~]# awk '{h[$1]++}END{for(name in h)print name,h[name]}' access.log
101.226.61.184 5
27.154.190.158 2
218.79.64.76 2
114.94.29.165 1
第一步: 定義數組信息
awk '{h[$1]}' access.log
說明: 數組中的元素就是你關注要統(tǒng)計的列的信息
第二步: 進行統(tǒng)計運算,編寫公式
awk '{h[$1]=h[$1]+1}' access.log
第三步: 編寫元素循環(huán)信息
awk '{h[$1]=h[$1]+1}END{for(name in h)}' access.log
第四步: 輸出結果信息???
awk '{h[$1]=h[$1]+1}END{for(name in h) print name,h[name]}' access.log
復制代碼
?將文本內容格式化輸出
原文如下:
job_name??? job_group
syncCommStockJob??? dataSync
syncStoreChnlJob??? dataSync
syncOrderJob??? dataSync
syncReportStoreJob??? dataSync
hdfsScanJob??? report
orderSaleDailyJob??? report
jdzmdOrdersJob??? report
jdCanJob??? report
使用awk格式化輸出后
cat xxx.txt | awk '{printf "%-30s%-15s\n",$1,$2}'??????????????
#%-30s表示輸出字符串,寬度30位(字符串如果過長宫仗,可以自己調整),左對齊.%-15s用來指定第二列的,左對齊,寬度15.兩個百分號之間可以沒有空格.使用\n對每一行的輸出加上換行符
job_name????????????????????? job_group?????
syncCommStockJob????????????? dataSync??????
syncStoreChnlJob????????????? dataSync??????
syncOrderJob????????????????? dataSync??????
syncReportStoreJob??????????? dataSync??????
hdfsScanJob?????????????????? report? ? ? ? ? ? ? ? ? ? ? ? ?