您好,登錄后才能下訂單哦!
awk 其實(shí)是一門編程語(yǔ)言,它,支持條件判斷、數(shù)組、循環(huán)等功能,我們可以把它理解成一個(gè)腳本語(yǔ)言解釋器
它與grep、sed被linux稱為"三劍客"
每個(gè)都有它的特長(zhǎng)
grep 更適合單純的去查找或者匹配文本
sed 更適合編輯匹配到的文本
awk 更適合格式化文本,對(duì)文本進(jìn)行較復(fù)雜格式處理
一、AWK基礎(chǔ)
awk的基本用法
格式
awk 動(dòng)作 文件名/文件名/awk/動(dòng)作
如果不指定任何參數(shù)直接使用awk
格式是這樣的
awk '{print}' 文件
直接回輸出整個(gè)文件,相當(dāng)于shell中的cat命令
示例
[root@zhaocheng ~]# awk '{print}' echo.sh
#!/bin/bash
echo "shucai"\b"niunai"
取free -m文件的第3列,這樣取的話,我們可以直接去使用free -m 先讓它輸出,然后通過(guò)管道再去取它的第三列,像取第三列的話,其實(shí)中間還是有分隔符的,也就是空格,不指定分隔符,默認(rèn)將空格作為分隔符了
[root@zhaocheng ~]# free -m |awk '{print $3}'
free
115
0
也可以去取多個(gè)列,以,分開(kāi),比如還是取free -m,取它的第2,3,4列
[root@zhaocheng ~]# free -m |awk '{print $2,$3,$4}'
used free shared
1838 116 339
0 0 0
另外awk還支持對(duì)文本的處理,添加字符串,像這個(gè)/etc/passwd文件中就是看起來(lái)是有列的,但是awk默認(rèn)不加-F是先按空格去提取的,而這個(gè)沒(méi)有所以添加了一個(gè)":"當(dāng)作文本的分隔符
格式
'{print $1,"hello"}'
'{print $1,$2,"hello"}'
'{print $1,"net",$2,"hello"}'
[root@zhaocheng ~]# awk -F ":" '{print $1,$2,"hello"}' test
root x hello
bin x hello
daemon x hello
adm x hello
lp x hello
sync x hello
shutdown x hello
halt x hello
[root@zhaocheng ~]# awk -F ":" '{print $1,"net",$2,"hello"}' test
root net x hello
bin net x hello
daemon net x hello
adm net x hello
lp net x hello
sync net x hello
shutdown net x hello
halt net x hello
而它的格式也是'{print $1}'中間不能加引號(hào),不然會(huì)當(dāng)成普通字符給輸出
[root@zhaocheng ~]# awk -F ":" '{print "$1"}' test
$1
$1
$1
$1
$1
$1
$1
$1
[root@zhaocheng ~]# awk -F ":" '{print '$1'}' test
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
比如打印文件,也就是相當(dāng)于cat命令一樣去用了,這里awk給出兩個(gè)用法,第一個(gè)就是可以使用awk '{print $0}'或者可以使用awk '{print}',這兩種都可以打印出來(lái)
[root@zhaocheng ~]# echo "Learn awk to improve your Linux skills" |awk '{print}'
Learn awk to improve your Linux skills
[root@zhaocheng ~]# echo "Learn awk to improve your Linux skills" |awk '{print $0}'
Learn awk to improve your Linux skills
而$0表示顯示整行,$NF表示當(dāng)前行分隔后的最后一列($0和$NF均為內(nèi)置變量)
每行的倒數(shù)第二列都可以寫成$(NF-1)
[root@zhaocheng ~]# awk -F: '{print $(NF-1)}' test
/root
/bin
/sbin
/var/adm
/var/spool/lpd
/sbin
/sbin
/sbin
[root@zhaocheng ~]# awk -F: '{print $NF}' test
/bin/bash
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/bin/sync
/sbin/shutdown
/sbin/halt
awk包含了兩種特殊的模式:BEGIN和END
BEGIN模式是指定了處理文本之前需要執(zhí)行的操作
END模式指定了處理完所有行之后所需要執(zhí)行的操作
這個(gè)BEGIN可以看到,即使我們后面指定了輸出源,但是它還是只打印了前面的字符,這也就是BEGIN的模式
[root@zhaocheng ~]# awk 'BEGIN{print "one","two"}'
one
[root@zhaocheng ~]# cat filetest
root:$1$dDTFylQ3$.vTZKpm7mrra9WMsxvBfW.:18241:0:99999:7
bin:*:17834:0:99999:7:dad
lp:*:17834:0:99999:7ada
sync:*:17834:0:99999:7:::gg
shutdown:*:17834:0:99999:7::da
halt:*:17834:0:99999:7::fsda
nginx:!!:18289::::::daaf
rabbitmq:!!:18297:::::dada
二、AWK的分隔符
awk的分隔符的使用,這里可以使用多種方法
-F 以什么為分隔符,來(lái)取第二列和第三列,-F:,-F"",-F''三種辦法都可以使用去取這個(gè)值
[root@zhaocheng ~]# awk -F: '{print $2,$3}' test
x 0
x 1
x 2
x 3
x 4
x 5
x 6
x 7
[root@zhaocheng ~]# awk -F ":" '{print $2,$3}' test
x 0
x 1
x 2
x 3
x 4
x 5
x 6
x 7
[root@zhaocheng ~]# awk -F ':' '{print $2,$3}' test
x 0
x 1
x 2
x 3
x 4
x 5
x 6
x 7
除了-F選項(xiàng),還能通過(guò)設(shè)置內(nèi)部變量的方式,指定awk的輸入分隔符,awk內(nèi)置變量FS可以用于指定輸入分隔符,但在使用變量時(shí),需要使用-v選項(xiàng),這里使用"",''都可以
[root@zhaocheng ~]# awk -v FS=':' '{print $2,$3}' test
x 0
x 1
x 2
x 3
x 4
x 5
x 6
x 7
[root@zhaocheng ~]# awk -v FS=":" '{print $2,$3}' test
x 0
x 1
x 2
x 3
x 4
x 5
x 6
x 7
awk的語(yǔ)法如下
**awk [選項(xiàng)] '模式{動(dòng)作}' file
而-F 就是選項(xiàng)的一種,一般用于指定分隔符 -v也是選項(xiàng)的一種,用于設(shè)置變量的值
而AWK的分隔符又分為輸入分隔符和輸出分隔符
輸入分隔符:也就是在輸入命令的時(shí)候以:,#為分隔符的時(shí)候這就是我們輸入的分隔符
輸出分隔符:也就是當(dāng)我們以#為分隔符的時(shí)候,輸出的結(jié)果會(huì)有空格隔開(kāi),這就是我們的輸出分隔符,實(shí)際上沒(méi)有輸出出來(lái)
當(dāng)然我們也可以將我們的輸出分隔符以awk的內(nèi)置變量OFS進(jìn)行輸出出來(lái)顯示,使用變量的時(shí)候需要加-v選項(xiàng),OFS相當(dāng)于以空格為分隔符了**
[root@zhaocheng ~]# cat test1
aaa bbb ooo
cccc dddd eeee
fffff ggggg hhhhh
kkkkk pppppp ssssss
[root@zhaocheng ~]# awk -v OFS="********" '{print $2,$3}' test1
bbb********ooo
dddd********eeee
ggggg********hhhhh
pppppp********ssssss
如果想以中間的符號(hào)為分隔符可以以FS=":"當(dāng)分隔符來(lái),同時(shí)指定輸入分隔符和輸出分隔符
[root@zhaocheng ~]# cat test
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
[root@zhaocheng ~]# awk -v FS=":" -v OFS="********" '{print $2,$3}' test
x********0
x********1
x********2
x********3
x********4
x********5
x********6
x********7
剛才使用的是輸出分隔符想讓中間的空格用指定輸出隔開(kāi),如果不使用中間的符號(hào)進(jìn)行隔開(kāi),直接進(jìn)行合并的話,只需要將$1 $2分開(kāi),不加,號(hào),一個(gè)是連接一起顯示,一個(gè)是以分隔符進(jìn)行顯示
[root@zhaocheng ~]# awk '{print $1 $2}' test1
aaabbb
ccccdddd
fffffggggg
kkkkkpppppp
[root@zhaocheng ~]# awk '{print $1,$2}' test1
aaa bbb
cccc dddd
fffff ggggg
kkkkk pppppp
三、AWK的變量
對(duì)于awk來(lái)說(shuō)“變量”又分為‘內(nèi)置變量和’自定義變量“ ,”輸入分隔符FS,和輸出分隔符“OFS都屬于內(nèi)置變量
awk的常用內(nèi)置變量以及作用
FS:輸入字段分隔符,默認(rèn)為空白字符
OFS:輸出字段分隔符,默認(rèn)為空白字符
RS:輸入記錄分隔(輸入換行符)指定輸入時(shí)的換行符
ORS:輸入記錄分隔符(輸出換行符),輸出時(shí)用指定符號(hào)代替換行符
NF:當(dāng)前行的字段的個(gè)數(shù)(即當(dāng)前行被分隔成了幾列),字段數(shù)量
NR:行號(hào),當(dāng)前處理的文本行的行號(hào)
FNR:各文件分別計(jì)數(shù)的行號(hào)
FILENAME:當(dāng)前文件名
ARGC:命令行的參數(shù)的個(gè)數(shù)
ARGV: 數(shù)組,保存的是命令行所給定的各參數(shù)
剛才的FS和OFS都用過(guò)了,F(xiàn)S是輸入分隔符,OFS是輸出分隔符,默認(rèn)都是空白字符,比如FS以什么為分隔符-v FS=":"以:為分隔符,輸出的時(shí)候一般不加后門的OFS顯示以空格分隔,如果在輸出格式添加,需要指定-v OFS=""將空格替換成來(lái)展示
內(nèi)置變量NR、NF
剛才說(shuō)到NR,其實(shí)就是當(dāng)前文本的行號(hào),一共幾行
NF就是一行中有幾列,一般以空格為分隔符
這里一共4列,使用NR直接顯示了行號(hào)
[root@zhaocheng ~]# cat test1
aaa bbb ooo
cccc dddd eeee
fffff ggggg hhhhh
kkkkk pppppp ssssss
[root@zhaocheng ~]# awk '{print NR}' test1
1
2
3
4
這里每行中有3列,所以使用NF就能統(tǒng)計(jì)出有多少列
[root@zhaocheng ~]# awk '{print NR,NF}' test1
1 3
2 3
3 3
4 3
統(tǒng)計(jì)test文件有多少行,使用行號(hào)進(jìn)行排序
可以使用awk的{print $0 NR}'
[root@zhaocheng ~]# awk '{print NR,$0 }' test
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
或者使用cat -n 也是統(tǒng)計(jì)行號(hào)的
[root@zhaocheng ~]# awk '{print}' test |cat -n
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
在bash語(yǔ)法中一般使用變量比如打印第一行需要$1,第二行$2,那么在awk中,不管使用內(nèi)置變量還是自定義變量都不需要加$
內(nèi)置變量FNR
這個(gè)一般是處理多個(gè)文件的同時(shí)來(lái)記錄行號(hào)的內(nèi)置變量,如果匹配多個(gè)文件的話,使用NR來(lái)記錄行號(hào)只會(huì)按順序直接排列,使用FNR會(huì)分開(kāi)排列
[root@zhaocheng ~]# awk '{print NR,$0}' test test1
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 aaa bbb ooo
10 cccc dddd eeee
11 fffff ggggg hhhhh
12 kkkkk pppppp ssssss
[root@zhaocheng ~]# awk '{print FNR,$0}' test test1
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
1 aaa bbb ooo
2 cccc dddd eeee
3 fffff ggggg hhhhh
4 kkkkk pppppp ssssss
內(nèi)置變量RS
RS是輸入行分隔符,如果不指定,默認(rèn)的行分隔符就是我們理解的回車換行
[root@zhaocheng ~]# awk -v RS=" " '{print NR,$0}' test1
1 aaa
2 bbb
3 ooo
cccc
4 dddd
5 eeee
fffff
6 ggggg
7 hhhhh
kkkkk
8 pppppp
9 ssssss
內(nèi)置變量ORS
這個(gè)和ORS的換行符差不多,只不過(guò)在指定輸出行分隔符+++的時(shí)候另?yè)Q一行
[root@zhaocheng ~]# awk -v ORS="++++" '{print NR,$0}' test1
1 aaa bbb ooo++++2 cccc dddd eeee++++3 fffff ggggg hhhhh++++4 kkkkk pppppp ssssss++++[root@zhaocheng ~]#
內(nèi)置變量FILENAME
FILENAME這個(gè)內(nèi)置變量從字面上,可以看出是什么意思,就是顯示文件名,使用指定多文件的FNR,統(tǒng)計(jì)行號(hào),在前面并打印出這個(gè)文件的名稱
[root@zhaocheng ~]# awk '{print FILENAME,FNR,$0}' test1 test
test1 1 aaa bbb ooo
test1 2 cccc dddd eeee
test1 3 fffff ggggg hhhhh
test1 4 kkkkk pppppp ssssss
test 1 root:x:0:0:root:/root:/bin/bash
test 2 bin:x:1:1:bin:/bin:/sbin/nologin
test 3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
test 4 adm:x:3:4:adm:/var/adm:/sbin/nologin
test 5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
test 6 sync:x:5:0:sync:/sbin:/bin/sync
test 7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
test 8 halt:x:7:0:halt:/sbin:/sbin/halt
內(nèi)置變量ARGV與ARGC
ARGV內(nèi)置變量表示的是一個(gè)數(shù)組,這個(gè)數(shù)組中保存的是命令行所給定的參數(shù)
[root@zhaocheng ~]# awk 'BEGIN{print "aaa"}' test test1
aaa
[root@zhaocheng ~]# awk 'BEGIN{print "aaa",ARGV[1]}' test test1
aaa test
[root@zhaocheng ~]# awk 'BEGIN{print "aaa",ARGV[2]}' test test1
aaa test1
[root@zhaocheng ~]# awk 'BEGIN{print "aaa",ARGV[1],ARGV[2]}' test test1
aaa test test1
從上面看出ARGV內(nèi)置變量表示的是一個(gè)數(shù)組,第一個(gè)數(shù)組就是test,第二個(gè)就是test1這個(gè)文件,而ARGV[0]這個(gè)就是我們本身的內(nèi)置變量awk
[root@zhaocheng ~]# awk 'BEGIN{print "aaa",ARGV[0],ARGV[1],ARGV[2]}' test test1
aaa awk test test1
而這個(gè)ARGC就是統(tǒng)計(jì)整個(gè)變量的數(shù)量
[root@zhaocheng ~]# awk 'BEGIN{print "aaa",ARGV[0],ARGV[1],ARGV[2],ARGC}' test test1
aaa awk test test1 3
自定義變量
自定義變量就是給用戶定義變量
[root@zhaocheng ~]# awk -v www="1234" 'BEGIN{print www}'
1234
[root@zhaocheng ~]# awk 'BEGIN{www="1234" ; print www}'
1234
一次性定義多個(gè)變量
[root@zhaocheng ~]# awk 'BEGIN{www="1234"; baidu="4567" ; print www , baidu}'
1234 4567
四、AWK格式化
對(duì)比print 和printf的區(qū)別,可以看出print 可以取$1的內(nèi)容,而printf不會(huì)輸出換行符,默認(rèn)會(huì)將文本輸出在一行里面
[root@zhaocheng ~]# awk '{print $1}' test1
aaa
cccc
fffff
kkkkk
[root@zhaocheng ~]# awk '{printf $1}' test1
aaaccccfffffkkkkk[root@zhaocheng ~]#
如果使用printf的格式替換符的話也可以將printf的格式打印出來(lái)
[root@zhaocheng ~]# awk '{printf "%s\n" ,$1}' test1
aaa
cccc
fffff
kkkkk
使用printf用法的是時(shí)候需要格式與列需要用逗號(hào)隔開(kāi),另外就是打印字符串的時(shí)候,可以通過(guò)\n,或者%s\n來(lái)替換
[root@zhaocheng ~]# printf "helloya\n"
helloya
[root@zhaocheng ~]# printf "%s\n" helloya
helloya
在使用awk中的printf動(dòng)作的時(shí)候需要注意點(diǎn)
1)使用printf動(dòng)作輸出的文本不會(huì)換行,如果需要換行,可以在對(duì)應(yīng)的格式替換符后加入\n進(jìn)行轉(zhuǎn)義
2)使用printf動(dòng)作時(shí),指定的格式與被格式化的文本之間,需要用逗號(hào)隔開(kāi)
3)使用printf動(dòng)作時(shí),格式中的格式替換符必須與被格式化的文本 一一對(duì)應(yīng)
可以利用格式替換符對(duì)文本中的每一列進(jìn)行格式化
針對(duì)空格進(jìn)行使用awk與printf打印格式化,默認(rèn)不使用輸入分隔符就是空格
[root@zhaocheng ~]# cat test1
aaa bbb ooo
cccc dddd eeee
fffff ggggg hhhhh
kkkkk pppppp ssssss
[root@zhaocheng ~]# awk '{printf "%s\n",$1}' test1
aaa
cccc
fffff
kkkkk
[root@zhaocheng ~]# awk '{printf "第一列 %s\n",$1}' test1
第一列 aaa
第一列 cccc
第一列 fffff
第一列 kkkkk
[root@zhaocheng ~]# awk '{printf " 第一列 %s 第二列 %s\n" ,$1,$2}' test1
第一列 aaa 第二列 bbb
第一列 cccc 第二列 dddd
第一列 fffff 第二列 ggggg
第一列 kkkkk 第二列 pppppp
[root@zhaocheng ~]# awk '{printf " 第二列 %s\n",$2}' test1
第二列 bbb
第二列 dddd
第二列 ggggg
第二列 pppppp
[root@zhaocheng ~]# awk '{printf " 第三列 %s\n",$3}' test1
第三列 ooo
第三列 eeee
第三列 hhhhh
第三列 ssssss
[root@zhaocheng ~]# awk '{printf "第一列 %s 第三列 %s\n",$1,$3}' test1
第一列 aaa 第三列 ooo
第一列 cccc 第三列 eeee
第一列 fffff 第三列 hhhhh
第一列 kkkkk 第三列 ssssss
[root@zhaocheng ~]# awk '{printf "第一列 %s 第二列 %s 第三列 %s\n",$1,$2,$3}' test1
第一列 aaa 第二列 bbb 第三列 ooo
第一列 cccc 第二列 dddd 第三列 eeee
第一列 fffff 第二列 ggggg 第三列 hhhhh
第一列 kkkkk 第二列 pppppp 第三列 ssssss
對(duì)于有分隔符的#來(lái)實(shí)現(xiàn)格式化
[root@zhaocheng ~]# cat test2
aaa#bbb#ooo
cccc#dddd#eeee
fffff#ggggg#hhhhh
kkkkk#pppppp#ssssss
普通使用 -v FS輸入分隔符,以#分隔
[root@zhaocheng ~]# awk -v FS="#" '{print $1,$2}' test2
aaa bbb
cccc dddd
fffff ggggg
kkkkk pppppp
普通使用-v OFS 輸出分隔符
[root@zhaocheng ~]# awk -v FS="#" -v OFS="####" '{print $1,$2}' test2
aaa####bbb
cccc####dddd
fffff####ggggg
kkkkk####pppppp
使用printf格式化輸出
[root@zhaocheng ~]# awk -v FS="#" '{printf "第一列 %s\n" ,$1}' test2
第一列 aaa
第一列 cccc
第一列 fffff
第一列 kkkkk
[root@zhaocheng ~]# awk -v FS="#" '{printf "第一列 %s 第二列 %s \n" ,$1,$2}' test2
第一列 aaa 第二列 bbb
第一列 cccc 第二列 dddd
第一列 fffff 第二列 ggggg
第一列 kkkkk 第二列 pppppp
結(jié)合BEGIN處理文本之前需要執(zhí)行的操作,與printf結(jié)合使用
[root@zhaocheng ~]# awk 'BEGIN{printf "%1s\t %s\n" ,"用戶名稱","用戶ID"}' test1
用戶名稱 用戶ID
[root@zhaocheng ~]# awk 'BEGIN{printf "%1s\t %s\n" ,"用戶名稱","用戶ID"} {printf "%1s\t %10s\n" , $1,$2}' test1
用戶名稱 用戶ID
aaa bbb
cccc dddd
fffff ggggg
kkkkk pppppp
以#為分隔符進(jìn)行格式化文本
[root@zhaocheng ~]# awk -v FS="#" 'BEGIN{printf "%1s\t %s\n" ,"用戶名稱","用戶ID"} {printf "%1s\t %10s\n" , $1,$2}' test2
用戶名稱 用戶ID
aaa bbb
cccc dddd
fffff ggggg
kkkkk pppppp
五、AWK模式(pattern)
對(duì)于awk使用語(yǔ)法
awk [options] 'Pattern {Action}' file1 file2 ...
awk -v FS=":" 'BEGIN{print/printf %1s\t %s\n","x x x", "xxxx"} {xxx}' file
對(duì)于options(選項(xiàng)),使用過(guò) -F選項(xiàng),也使用過(guò) -v選項(xiàng)
對(duì)于Acation(動(dòng)作),使用過(guò)print與printf
對(duì)于Pattern(模式),使用過(guò)BEGIN模式與END模式
下面熟悉一個(gè)awk的條件,也就是awk會(huì)先處理完當(dāng)前行,在處理下一行,如果我們不指定任何“條件”,awk會(huì)一行一行的處理文本中的每一行,如果我們指定來(lái)?xiàng)l件,只有滿足條件的的行才會(huì)被處理,不滿足條件的行就不會(huì)被處理,這就是awk中的模式
其實(shí)在當(dāng)awk進(jìn)行逐行處理的時(shí)候,會(huì)把pattern(模式)作為條件,判斷將要被處理的行是否滿足條件,是否能跟模式想匹配,如果匹配就處理,如果不匹配,則不進(jìn)行處理
NF==4之前我們使用NF的時(shí)候是統(tǒng)計(jì)有多少列每行,NF==4也就是有4列的行,然后打印出來(lái)
[root@zhaocheng ~]# awk 'NF==4 {print}' test1
fffff ggggg hhhhh bbbbb
[root@zhaocheng ~]# awk 'NF==5 {print}' test1
kkkkk pppppp ssssss xxxxxx mmmmmmmm
這就是awk使用到的關(guān)系表達(dá)式,比如==,<,>,<=,>=,也就是得到的結(jié)果為真時(shí),則滿足條件,與指定模式想匹配,滿足時(shí)就會(huì)執(zhí)行相應(yīng)的動(dòng)作。
示例
[root@zhaocheng ~]# cat test1
aaa bbb ooo
cccc dddd eeee
fffff ggggg hhhhh bbbbb
kkkkk pppppp ssssss xxxxxx mmmmmmmm
大于4列的行
[root@zhaocheng ~]# awk 'NF>4 {print $0}' test1
kkkkk pppppp ssssss xxxxxx mmmmmmmm
大于等于4列的行
[root@zhaocheng ~]# awk 'NF>=4 {print $0}' test1
fffff ggggg hhhhh bbbbb
kkkkk pppppp ssssss xxxxxx mmmmmmmm
小于等于4列的行
[root@zhaocheng ~]# awk 'NF<=4 {print $0}' test1
aaa bbb ooo
cccc dddd eeee
fffff ggggg hhhhh bbbbb
實(shí)際上awk有四種pattern模式
第一種就是BEGIN,表示在開(kāi)始處理文本之前,需要執(zhí)行的操作
第二種時(shí)END模式,表示將所有行都處理完畢后,需要執(zhí)行的操作
第三種就是關(guān)系運(yùn)算模式,剛才我們用到的NF==xx
第四種就是空模式,就是相當(dāng)于awk '{print $0}' file,空模式會(huì)匹配文本中每一行,所以每一行都滿足條件,每一行都會(huì)執(zhí)行動(dòng)作
熟悉一下END模式,ENGIN就是開(kāi)始先處理什么,END就是最后處理什么
示例
[root@zhaocheng ~]# awk 'BEGIN{print "開(kāi)始","開(kāi)始"} {print $1,$2} END{print "結(jié)束","結(jié)束"}' test1
開(kāi)始 開(kāi)始
aaa bbb
cccc dddd
fffff ggggg
kkkkk pppppp
結(jié)束 結(jié)束
六、AWK模式(Pattern) 正則表達(dá)式
awk的另外兩種常用模式,正則模式與行范圍模式
正則模式:顧名思義與正則表達(dá)式有關(guān),模式可以理解為條件,當(dāng)不指定模式時(shí),文本中的每一行都會(huì)執(zhí)行對(duì)應(yīng)的動(dòng)作,當(dāng)有被模式匹配到的,符合條件的行才會(huì)執(zhí)行相應(yīng)的動(dòng)作,正則模式可以理解為,把正則表達(dá)式當(dāng)作條件,能與正則匹配的行,就算滿足條件,滿足條件的行才會(huì)執(zhí)行相應(yīng)的動(dòng)作,不能被正則匹配到的行,則不會(huì)執(zhí)行對(duì)應(yīng)的動(dòng)作
使用grep/awk找出/etc/passwd山以ftp開(kāi)頭的行
[root@zhaocheng ~]# grep "^ftp" /etc/passwd
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
[root@zhaocheng ~]# awk '/^ftp/{print $0}' /etc/passwd
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
不管是使用grep命令,還是使用awk命令,都使用了相同的正則表達(dá)式^ftp
唯一區(qū)別就是,在grep命令中,直接使用了正則表達(dá)式,而在awk中正則表達(dá)式被放入到了兩個(gè)斜線中
grep "正則表達(dá)式" /etc/passwd
awk '/正則表達(dá)式'/{print $0}' /etc/passwd
而awk的優(yōu)勢(shì)就是格式化輸出
[root@zhaocheng ~]# awk -v FS=":" 'BEGIN{printf "%-10s%-10s\n","用戶名稱","用戶ID"} /^ftp/{printf "%-10s\t%-10s\n",$1,$3}' /etc/passwd
用戶名稱 用戶ID
ftp 14
使用grep的時(shí)候利用正則表達(dá)式可以$就可以輸出,使用awk輸出的話,就需要添加轉(zhuǎn)義符
[root@zhaocheng ~]# grep "/bin/bash$" /etc/passwd
root:x:0:0:root:/root:/bin/bash
[root@zhaocheng ~]# awk '/\/bin\/bash$/{print $0}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
awk的行匹配模式
[root@zhaocheng ~]# awk '/helm/{print $0}' test6
helm.org
匹配行語(yǔ)法
awk '/正則表達(dá)式/{動(dòng)作}' / file
awk '/正則1/,/正則2/{動(dòng)作}' / file
可以打印大于=3行,小于等于4行的
[root@zhaocheng ~]# awk 'NR>=3 && NR<=4 {print $0}' test6
rabbitmq.com
zookpeer.com
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。