一著角、簡(jiǎn)介
awk命令是一種編程語(yǔ)言,用于在linux/unix下對(duì)文本和數(shù)據(jù)進(jìn)行掃描和處理的工具技俐,其數(shù)據(jù)來(lái)源可以為標(biāo)準(zhǔn)輸入乘陪、文件、管道等等雕擂。awk命令會(huì)從第一行輸入開(kāi)始逐行掃描至最后一行啡邑,尋找其中匹配特定模式的行,并在相應(yīng)的行上執(zhí)行用戶指定的操作井赌。Awk命令的基本架構(gòu)由模式匹配和處理動(dòng)作組成谤逼,默認(rèn)處理動(dòng)作為print打印行。
二仇穗、awk命令的使用
1流部、命令格式
gawk [options] 'program...' FILE ...
2、常見(jiàn)選項(xiàng)
-F fs:指明字段分隔符仪缸;
-v var=value:自定義變量贵涵;
-f programfile:從文件中讀取program命令;
3恰画、program語(yǔ)句
其program語(yǔ)句的常見(jiàn)格式為:PATTERN{action宾茂,statements}
,其中多個(gè)program語(yǔ)句之間通過(guò);
分隔拴还。
- 其中PATTERN格式為:
1)empty:空模式跨晴,表示匹配每一行,如:awk -F: '{print $1,$3}' /etc/passwd 表示以:
為分隔符片林,打印每行的第一和第三個(gè)字段 端盆。
2)/regular expression/:僅處理能夠被此模式匹配到的行,如:awk -F: '/^root/{print $1,$3}' /etc/passwd费封,表示以:
為分隔符焕妙,打印以root開(kāi)頭的行的第一和第三個(gè)字段;
3)/PATTERN1/,/PATTERN2/:表示僅處理從第一個(gè)被pattern1匹配到行弓摘,到第一個(gè)被pattern2所匹配的行之間的所有行焚鹊,如:awk -F: '/root/,/shutdown/{print $1,$3}' /etc/passwd,表示以:
為分隔符韧献,打印從第一個(gè)以root開(kāi)頭的行到第一個(gè)以shutdown開(kāi)頭的行之間的所有行的第一和第三個(gè)字段末患。
4)relation expression:使用關(guān)系表達(dá)式進(jìn)行匹配,只有結(jié)果會(huì)真的行才會(huì)被處理锤窑,如:awk -F: '(NR>=10&&NR<=20){print $1,$3}' /etc/passwd璧针,表示以:
為分隔符,打印10-20行的第一和第三個(gè)字段渊啰;
5)BEGIN{}和END{}:
BEGIN{}:表示在開(kāi)始處理行前執(zhí)行一次指定的操作探橱;
END{}:表示在結(jié)束對(duì)行的處理后執(zhí)行一次指定的操作申屹;
如:awk -F: 'BEGIN{print "This is the begin."};{print $1,$3};END{print "This is the end."}' /etc/passwd,表示在執(zhí)行行打印操作前走搁,先打印指定的字符串"This is the begin."独柑,在執(zhí)行行打印操作后再打印字符串“This is the end.”
- program語(yǔ)句的變量
program中內(nèi)置了一些變量,在編寫(xiě)program語(yǔ)句時(shí)能夠直接調(diào)用相應(yīng)的變量私植,進(jìn)而簡(jiǎn)化語(yǔ)句。調(diào)用內(nèi)建變量時(shí)無(wú)需加$
车酣。
FS:輸入字段分隔符曲稼,默認(rèn)為空白字符;
OFS:輸出字段分隔符湖员,默認(rèn)為空白字符贫悄;
RS:輸入時(shí)的換行符;
ORS:輸出時(shí)的換行符娘摔;
NF:每行的字段數(shù)窄坦,$NF表示最后一個(gè)字段;
NR:表示行數(shù)凳寺;
FNR:若提供多個(gè)文件鸭津,則分別計(jì)算各文件的行數(shù);
FILENAME:當(dāng)前文件名肠缨;
ARGC:命令行參數(shù)的個(gè)數(shù)逆趋;
ARGV:參數(shù)數(shù)組,保存的是命令行給定的各參數(shù)晒奕;
另外也可以在awk命令中自定義相關(guān)的變量闻书,可以使用-v選項(xiàng)自定義變量,也可以在語(yǔ)句當(dāng)中進(jìn)行賦值操作脑慧,如:awk 'BEGIN{test="hello awk"; print test}'魄眉、ls -l | awk '/root/{hello="this is a test.";print $3,hello}'
- action
常見(jiàn)的action動(dòng)作有:print、printf
1)print命令
其使用格式類(lèi)似于print item1,item2,...
闷袒,使用逗號(hào)作為分隔符坑律,輸出的item可以為字符串,也可以為數(shù)值霜运,也可以為當(dāng)前記錄的字段脾歇、變量或表達(dá)式等。如果省略了item淘捡,則相當(dāng)于print $0打印所有行藕各。
2)printf命令
printf命令常用于格式化輸出awk命令的執(zhí)行結(jié)果信息。其格式類(lèi)似于printf FORMAT,item1,item2...
焦除,其中必須指定FORMAT格式激况;如需換行,需手動(dòng)添加\n換行符;在FORMAT中需要分別為后面的每個(gè)item指定一個(gè)格式符乌逐。
其對(duì)應(yīng)的格式符有:
%c: 顯示字符的ASCII碼竭讳;
%d, %i: 顯示十進(jìn)制整數(shù);
%e, %E: 科學(xué)計(jì)數(shù)法數(shù)值顯示浙踢;
%f:顯示為浮點(diǎn)數(shù)绢慢;
%g, %G:以科學(xué)計(jì)數(shù)法或浮點(diǎn)形式顯示數(shù)值;
%s:顯示字符串洛波;
%u:無(wú)符號(hào)整數(shù)胰舆;
%%: 顯示%自身
其中還可以使用以下修飾符對(duì)格式符進(jìn)行輸出格式的整理:
#[.#]:第一個(gè)#數(shù)字控制格式符顯示的寬度;第二個(gè)#數(shù)字表示格式符顯示的內(nèi)容的精確度蹬挤,只顯示最大長(zhǎng)度為#的格式符內(nèi)容缚窿;
-:左對(duì)齊,默認(rèn)為右對(duì)齊焰扳;
+:顯示數(shù)值的符號(hào)倦零;
如下示例:
[root@localhost ~]# awk -F: '{printf "The user:%-20s User ID:%15d\n",$1,$3} ' /etc/passwd
The user:root User ID: 0
The user:bin User ID: 1
The user:daemon User ID: 2
The user:adm User ID: 3
The user:lp User ID: 4
The user:sync User ID: 5
The user:shutdown User ID: 6
The user:halt User ID: 7
The user:mail User ID: 8
The user:operator User ID: 11
The user:games User ID: 12
The user:ftp User ID: 14
The user:nobody User ID: 99
The user:avahi-autoipd User ID: 170
The user:systemd-bus-proxy User ID: 999
The user:systemd-network User ID: 998
The user:dbus User ID: 81
The user:polkitd User ID: 997
The user:tss User ID: 59
The user:postfix User ID: 89
The user:sshd User ID: 74
-
條件表達(dá)式
awk命令的program語(yǔ)句也支持通過(guò)條件表達(dá)式來(lái)判斷控制,其表達(dá)式支持常見(jiàn)的算術(shù)吨悍、賦值扫茅、比較等操作符,如:+畜份,-诞帐,*,/爆雹,%停蕉,=,+=钙态,>慧起,<,~等等的操作符册倒,也支持邏輯操作與或非蚓挤,其格式為:
awk [optioins] '{selector?if-true-expression:if-false-expression;action statements}' /PATH/TO/SOMEFILE
如根據(jù)用戶ID判斷對(duì)應(yīng)用戶是系統(tǒng)用戶還是普通用戶:
[root@localhost ~]# awk -F: '{$3>=1000?usertype="this is a common user.":usertype="This is a system user.";printf "%20s:%-s\n",$1,usertype}' /etc/passwd
root:This is a system user.
bin:This is a system user.
daemon:This is a system user.
adm:This is a system user.
lp:This is a system user.
sync:This is a system user.
shutdown:This is a system user.
halt:This is a system user.
mail:This is a system user.
operator:This is a system user.
games:This is a system user.
ftp:This is a system user.
nobody:This is a system user.
pegasus:This is a system user.
avahi-autoipd:This is a system user.
ods:This is a system user.
systemd-bus-proxy:This is a system user.
systemd-network:This is a system user.
dbus:This is a system user.
polkitd:This is a system user.
sssd:This is a system user.
apache:This is a system user.
三、使用案例
- 格式化打印當(dāng)前系統(tǒng)的用戶列表
[root@localhost ~]# awk -F: 'BEGIN{print "User lists"};{printf "User:%-25s\n",$1};END{print "This is the end."}' /etc/passwd
User lists
User:root
User:bin
.....
User:nologin
User:hadoop
This is the end.
[root@localhost ~]#
- 搜索打印以/bin/bash為默認(rèn)shell的用戶信息:
[root@localhost ~]# awk -F: '$7~/.*bash\>/{print $0}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
amandabackup:x:33:6:Amanda user:/var/lib/amanda:/bin/bash
postgres:x:26:26:PostgreSQL Server:/var/lib/pgsql:/bin/bash
centos:x:1001:1001::/home/centos:/bin/bash
federo:x:1002:1002::/home/federo:/bin/bash
counter:x:1003:1004::/home/counter:/bin/bash
charlie:x:1004:1005::/home/charlie:/bin/bash
Jone:x:1006:1007::/Jone:/bin/bash
Williom:x:1200:1005::/home/Williom:/bin/bash
mageia:x:1100:1100::/home/linux:/bin/bash
bash:x:2003:2003::/home/bash:/bin/bash
testbash:x:2004:2004::/home/testbash:/bin/bash
basher:x:2005:2005::/home/basher:/bin/bash
hadoop:x:2007:2007::/home/hadoop:/bin/bash
- 獲取系統(tǒng)網(wǎng)卡的Ip地址
[root@localhost ~]# ifconfig | awk '/inet\>/{print $2}'
188.88.88.42
127.0.0.1
192.168.122.1
- 對(duì)比兩個(gè)文件的內(nèi)容
[root@localhost tmp]# cat a.sh
hello,world
i am charlie
this is my linux
magedeu
[root@localhost tmp]# cat b.sh
1
hello,world
2
i am charlie
3
this is my linux
4
magedeu
[root@localhost tmp]# awk 'FNR==NR{a[$0];next}{if($0 in a)print $0}' a.sh b.sh
hello,world
i am charlie
this is my linux
magedeu
上述awk命令在FNR和NR的等式成立的時(shí)候驻子,將文件a.sh每行的內(nèi)容作為數(shù)組a下標(biāo)灿意,然后執(zhí)行next跳過(guò)后續(xù)if判斷語(yǔ)句;當(dāng)FNR和NR的等式不成立的時(shí)候崇呵,不執(zhí)行a[$0];next缤剧,執(zhí)行后面的if語(yǔ)句,判斷b.sh中的每行內(nèi)容是否為a數(shù)組中的元素下標(biāo)域慷,是的話就打印該行信息荒辕。
同理汗销,利用取反找出不同的行:
[root@localhost tmp]# awk 'FNR==NR{a[$0];next}{if (!($0 in a))print $0}' a.sh b.sh
1
2
3
4
- 從文件中讀取program語(yǔ)句執(zhí)行awk命令
這里以上面文件對(duì)比的命令為例:
[root@localhost tmp]# cat awk.sh
FNR==NR{
a[$0];
next
}
{
if (!($0 in a))
print $0
}
[root@localhost tmp]# awk -f awk.sh a.sh b.sh
1
2
3
4
如有錯(cuò)誤,歡迎指點(diǎn)~