gawk 語法介紹及其實例
§·awk介紹
Linux文本處理三劍客:grep sed 和 awk 。其中grep是一種文本過濾工具,sed是文本行編輯器,而awk是一種報表生成器,就是對文件進行格式化處理的,這里的格式化不是文件系統的格式化,而是對文件的內容進行的各種排版,進而格式化顯示。
在linux之上我們使用awk是GUN awk簡稱gawk,并且gawk其實就是awk的連接文件,gawk是一種過程是編程語言,gawk還支持條件判斷,數組,循環等各種編程語言中所有的可以使用的功能,因此我們還可以把gawk成為一種腳本語言解釋器。
§·awk基本用法
※·基本用法:
awk [options] ‘program’ var=value file…
awk [options] -f programfile var=value file…
awk [options] 'BEGIN{ action;… } pattern { action;… } END{ action;… }' file …
#需要處理的文本每一行我們稱之為 記錄
#BEGIN{ action;… } 處理記錄前的需要執行的動作,比如:打印提示符等
#pattern { action;… } 匹配時處理的動作
#END{ action;… } 處理一條記錄后需要執行的東西,比如:打印結束語,或求和,求積等等。
awk程序通常由:BEGIN語句塊、能夠使用模式匹配的通用語句塊、END語句塊,共3部分組成
program : 通常是被單引號或雙引號中的編程語言
pattern : 模式
action;… : 動作語句,可以是由多個語句組成,各個語句使用分號分隔,如: print printf
·選項:
-F 指明輸入時用到的字段分隔符
-v var=value: 自定義變量
※·基本格式:
awk [options] 'program' file…
·#[options]
-f /PATH/FROM/AWK_SCRIPT:指明后面需要運用的 awk腳本
-F :指明分隔符
-v :聲明變量
program:pattern{action statements;..}
pattern和action:
?pattern部分決定動作語句何時觸發及觸發事件
(BEGIN,END)
?action statements對數據進行處理,放在{}內指明
(print, printf)
分割符、域和記錄
?awk執行時,由分隔符分隔的字段(域)標記$1,$2..$n稱為域標識。$0為所有域,注意:和shell中變量$符含義不同
?文件的每一行稱為記錄
?省略action,則默認執行print $0 的操作。
※·awk工作原理
·第一步:
執行 BEGIN{action;… } 語句塊中的語句
比如: [root@centos68 ~]# tail -n5 /etc/passwd | awk 'BEGIN{FS=":";f=1}{print$f}' #BEGIN{FS=”:”;f=1} : 記錄處理前,表明分隔符為: 變量f=1 #{print$f} : 沒有pattern表示每條記錄都匹配,打印第一列 sshd tcpdump admin chen mockbuild [root@centos68 ~]#
·第二步:
從文件或標準輸入(stdin)讀取一行,然后執行pattern{ action;… }語句塊,它逐行掃描文件,從第一行到最后一行重復這個過程,直到文件全部被讀取完畢。
·第三步:
當讀至輸入流末尾時,執行END{action;…}語句塊
·BEGIN 語句塊的作用
BEGIN語句塊在awk開始從輸入流中讀取行之前被執行,這是一個可選的語句塊,比如變量初始化、打印輸出表格的表頭等語句通常可以寫在BEGIN語句塊中
·END語句塊的作用
END語句塊在awk從輸入流中讀取完所有的行之后即被執行,比如打印所有行的分析結果這類信息匯總都是在END語句塊中完成,它也是一個可選語句塊
·pattern語句塊
pattern語句塊中的通用命令是最重要的部分,也是可選的。如果沒有提供pattern語句塊,則默認執行{ print },即打印每一個讀取到的行,awk讀取的每一行都會執行該語句塊
※·print格式:print item1, item2, …
·要點:
?(1) 逗號分隔符
?(2) 輸出的各item可以字符串,也可以是數值;當前記錄的字段、變量或awk的表達式
?(3) 如省略item,相當于print $0
·print格式示例:
awk '{print "hello,awk"}'
[root@centos68 ~]# awk '{print "hello ,awk"}' #awk支持標準的輸入,后面沒有接文件或沒有管道輸入導入,就會出現交互式輸入的情況 #輸入一行,由于沒有patterm,所以就匹配你所有的行,在打印 hello,awk 的估計字符串 1 hello ,awk 2 hello ,awk 3 hello ,awk 4 hello ,awk 5 hello ,awk [root@centos68 ~]#
awk -F: '{print "wang"}' /etc/issue
[root@centos68 ~]# awk -F: '{print "wang"}' /etc/issue #處理/etc/issue的每一行,每一條記錄處理完打印固定字符串 wang wang wang wang wang wang wang wang [root@centos68 ~]#
awk –F: ‘{print $1}’ /etc/passwd
[root@centos68 isolinux]# awk -F: '{print$1}' /etc/passwd root bin daemon adm lp sync shutdown halt mail uucp operator games gopher ftp nobody dbus usbmuxd rpc rtkit avahi-autoipd vcsa abrt rpcuser nfsnobody haldaemon ntp apache saslauth postfix mysql gdm pulse sshd tcpdump admin chen mockbuild
awk –F: ‘{print $0}’ /etc/passwd #打印每一行
awk–F: ‘{print $1”\t”$3}’ /etc/passwd
[root@centos68 isolinux]# awk -F: '{print$1 "\t" $3}' /etc/passwd #打印 /etc/passwd 的第1列和第3列的并且以tab鍵分隔 root 0 bin 1 daemon 2 adm 3 lp 4 sync 5 shutdown 6 halt 7 mail 8 uucp 10 operator 11 games 12 gopher 13 ftp 14 nobody 99 dbus 81 usbmuxd 113 rpc 32 rtkit 499 avahi-autoipd 170 vcsa 69 abrt 173 rpcuser 29 nfsnobody 65534 haldaemon 68 ntp 38 apache 48 saslauth 498 postfix 89 mysql 27 gdm 42 pulse 497 sshd 74 tcpdump 72 admin 500 chen 501 mockbuild 502 [root@centos68 isolinux]#
tail –3 /etc/fstab | awk ‘{print $2,$4}’
[root@centos68 isolinux]# tail -n3 /etc/fstab | awk '{print $2"\t" $4}' /sys defaults /proc defaults /mnt/sda6 defaults,usrquota,grpquota [root@centos68 isolinux]#
§·awk變量
※·awk內建變量
FS:輸入字段分隔符,默認為空白字符
awk -v FS=':' '{print $1,$3,$7}’ /etc/passwd
awk –F: '{print $1,$3,$7}’ /etc/passwd
OFS:輸出字段分隔符,默認為空白字符
tail -n3 /etc/fstab | awk -v OFS='—–' '{print $1,$2}'
[root@centos68 isolinux]# tail -n3 /etc/fstab | awk -v OFS='-----' '{print $1,$2}' sysfs-----/sys proc-----/proc /dev/sda6-----/mnt/sda6
RS:輸入記錄分隔符,指定輸入時的換行符,原換行符仍有效
tail -n1 /etc/passwd | awk -F: -v RS=':' '{print$1"—"}'
[root@centos68 ~]# tail -n1 /etc/passwd mockbuild:x:502:502::/home/mockbuild:/bin/bash
[root@centos68 ~]# tail -n1 /etc/passwd | awk -F: -v RS=':' '{print$1"---"}' mockbuild--- x--- 502--- 502--- --- /home/mockbuild--- /bin/bash --- [root@centos68 ~]# #從awk的結果來開看,RS的作用會把 一條記錄中的 : 做為行結尾符,只要出現了 : 就會換行,在把每一行保存在變量$1中。
ORS:輸出記錄分隔符,輸出時用指定符號代替換行符
awk-v RS=' ' -v ORS='###'‘{print }’ /etc/passwd
[root@centos68 ~]# tail -n3 /etc/passwd | awk -F: -v ORS='#####' '{print$1,$3}' admin 500#####chen 501#####mockbuild 502#####[root@centos68 ~]#
NF:字段數量
Awk -F:‘{print NF}’ /etc/fstab, 引用內置變量不用$
Awk -F: '{print $(NF-1)}' /etc/passwd
[root@centos68 ~]# tail -n3 /etc/passwd | awk -F: '{print NF}' 7 7 7 [root@centos68 ~]# tail -n3 /etc/passwd | awk -F: '{print $(NF-1)}' /home/admin /home/chen /home/mockbuild [root@centos68 ~]#
NR:行號
awk '{print NR}' /etc/fstab; awk END'{print NR}' /etc/fstab
[root@centos68 ~]# tail -n3 /etc/passwd | awk -F: '{print NR"\t" $0}' 1 admin:x:500:500:chenjiashun:/home/admin:/bin/bash 2 chen:x:501:501::/home/chen:/bin/bash 3 mockbuild:x:502:502::/home/mockbuild:/bin/bash [root@centos68 ~]# tail -n3 /etc/passwd | awk -F: 'END{print NR"\t" $0}' 3 mockbuild:x:502:502::/home/mockbuild:/bin/bash [root@centos68 ~]# tail -n3 /etc/passwd | awk -F: 'BEGIN{print NR"\t" $0}' 0 [root@centos68 ~]#
FNR:各文件分別計數,行號
awk '{print FNR}' /etc/fstab /etc/inittab
#兩個文件分別統計行號,并且只打印行號
FILENAME:當前文件名
awk 'END{print FILENAME}’ /etc/fstab
[root@centos68 ~]# awk 'END{print FILENAME}' /etc/passwd #處理完最后一樣后,打印出文件的名稱 /etc/passwd [root@centos68 ~]#
ARGC:命令行參數的個數
awk '{print ARGC}’ /etc/fstab /etc/inittab
awk ‘BEGIN {print ARGC}’ /etc/fstab /etc/inittab
[root@centos68 ~]# awk 'BEGIN{print ARGC}' /etc/issue 2 [root@centos68 ~]# awk '{print ARGC}' /etc/issue 2 2 2 2 2 2 2 [root@centos68 ~]# awk '{print ARGC}' /etc/issue /etc/issue 3 3 3 3 3 3 3 3 3 3 3 3 3 3 [root@centos68 ~]#
ARGV:數組,保存的是命令行所給定的各參數
awk ‘BEGIN {print ARGV[0]}’ /etc/fstab /etc/inittab
awk ‘BEGIN {print ARGV[1]}’ /etc/fstab /etc/inittab
[root@centos68 ~]# awk 'BEGIN{print ARGV[0]}' /etc/{fstab,passwd} awk [root@centos68 ~]# awk 'BEGIN{print ARGV[1]}' /etc/{fstab,passwd} /etc/fstab [root@centos68 ~]# awk 'BEGIN{print ARGV[2]}' /etc/{fstab,passwd} /etc/passwd [root@centos68 ~]# awk 'BEGIN{print ARGV[3]}' /etc/{fstab,passwd} [root@centos68 ~]# awk 'BEGIN{print ARGC}' /etc/{fstab,passwd} 3 [root@centos68 ~]#
※·自定義變量
(1) -v var=value
變量名區分字符大小寫
(2) 在program中直接定義
v示例:
awk -v test='hello gawk' '{print test}' /etc/fstab
awk -v test='hello gawk' 'BEGIN{print test}'
awk 'BEGIN{test="hello,gawk";print test}'
[root@centos68 ~]# awk -v test='helol gawk' 'BEGIN{print test}' /etc/fstab helol gawk [root@centos68 ~]# awk -v test='helol gawk' 'END{print test}' /etc/fstab helol gawk [root@centos68 ~]# awk -v test='helol gawk' '{print test}' /etc/issue helol gawk helol gawk helol gawk helol gawk helol gawk helol gawk helol gawk [root@centos68 ~]# awk 'BEGIN{test="helol,gawk "; print test}' /etc/issue helol,gawk [root@centos68 ~]#
§·awk格式化
※·printf命令
◎·格式化輸出:
printf“FORMAT”, item1, item2, …
(1) 必須指定FORMAT
(2) 不會自動換行,需要顯式給出換行控制符,\n
(3) FORMAT中需要分別為后面每個item指定格式符
◎·格式符:
與item一一對應
%c: 顯示字符的ASCII碼
%d, %i: 顯示十進制整數
%e, %E:顯示科學計數法數值
%f:顯示為浮點數
%g, %G:以科學計數法或浮點形式顯示數值
%s:顯示字符串
%u:無符號整數
%%: 顯示%自身
◎·修飾符:
#[.#]:第一個數字控制顯示的寬度;第二個#表示小數點后精度,%3.1f
-: 左對齊(默認右對齊)%-15s
+:顯示數值的正負符號%+d
※·printf示例
?awk -F: ‘{printf "%s",$1}’ /etc/passwd
[root@centos68 ~]# tail -n5 /etc/passwd | awk -F: '{printf "%s",$1}' #printf默認是不會換行的,及打出來的一行字符串 sshdtcpdumpadminchenmockbuild[root@centos68 ~]# tail -n5 /etc/passwd | awk -F: '{printf "%s\n",$1}' #%s表示的$1的類型為字符串類型 sshd tcpdump admin chen mockbuild [root@centos68 ~]#
?awk -F: ‘{printf "%s\n",$1}’ /etc/passwd
[root@centos68 ~]# tail -n5 /etc/passwd | awk -F: '{printf "%s",$1}' #printf默認是不會換行的,及打出來的一行字符串 sshdtcpdumpadminchenmockbuild[root@centos68 ~]# tail -n5 /etc/passwd | awk -F: '{printf "%s\n",$1}' #%s表示的$1的類型為字符串類型 sshd tcpdump admin chen mockbuild [root@centos68 ~]#
?awk -F: ‘{printf "Username: %s, UID:%d\n",$1,$3}’ /etc/passwd
[root@centos68 ~]# tail -n5 /etc/passwd| awk -F: '{printf "Username=%s----UID=%d\n",$1,$3}' Username=sshd----UID=74 Username=tcpdump----UID=72 Username=admin----UID=500 Username=chen----UID=501 Username=mockbuild----UID=502 [root@centos68 ~]#
?awk -F: ‘{printf "Username: %-15s, UID:%d\n",$1,$3}’ /etc/passwd
[root@centos68 ~]# tail -n5 /etc/passwd| awk -F: '{printf "Username:%15s UID=%d\n",$1,$3}' Username: sshd UID=74 Username: tcpdump UID=72 Username: admin UID=500 Username: chen UID=501 Username: mockbuild UID=502 [root@centos68 ~]# tail -n5 /etc/passwd| awk -F: '{printf "Username:%-10s UID=%d\n",$1,$3}' # %-10s 表示為 $1字段控制在10個字符串內,左對齊,默認為右對齊 # %d\n 表示為$3為數字類型,并且尾部換行 Username:sshd UID=74 Username:tcpdump UID=72 Username:admin UID=500 Username:chen UID=501 Username:mockbuild UID=502
?tail -n5 /etc/passwd| awk -F: '{printf "Username:%-10s UID=%-10d Shell=%s\n",$1,$3,$NF}'
[root@centos68 ~]# tail -n5 /etc/passwd| awk -F: '{printf "Username:%-10s UID=%-10d Shell=%s\n",$1,$3,$NF}' #Username:%-10s :$1 字符串類型10個字符內左對齊 #UID=%-10d : $3 數字類型5個左對齊 #Shell=%s\n" : $NF 最后一個分段字符串類型 換行 Username:sshd UID=74 Shell=/sbin/nologin Username:tcpdump UID=72 Shell=/sbin/nologin Username:admin UID=500 Shell=/bin/bash Username:chen UID=501 Shell=/bin/bash Username:mockbuild UID=502 Shell=/bin/bash [root@centos68 ~]#
§·awk操作符
◎·算術操作符:
x+y, x-y, x*y, x/y, x^y, x%y
-x: 轉換為負數
+x: 轉換為數值
◎·字符串操作符:
沒有符號的操作符,字符串連接
◎·賦值操作符:
=, +=, -=, *=, /=, %=, ^=
++, —
◎·比較操作符:
>, >=, <, <=, !=, ==
◎·模式匹配符:
~:左邊是否和右邊匹配包含
!~:是否不匹配
cat /etc/passwd|awk'$0 ~ /root/'|wc-l
cat /etc/passwd|awk'$0 !~ /root/'|wc-l
[root@centos68 ~]# cat /etc/issue #issue文件內容 CentOS release 6.8 (Final) Kernel \r on an \m ============================== Welcome to my hostname SA! Welcome to my hostname SC ============================== [root@centos68 ~]# cat /etc/issue | awk '$0~/hostname/{print}' #顯示包含 hostname 的行 Welcome to my hostname SA! Welcome to my hostname SC [root@centos68 ~]# cat /etc/issue | awk '$0!~/hostname/{print}' #顯示不包含 hostname 的行 CentOS release 6.8 (Final) Kernel \r on an \m ============================== ==============================
◎·邏輯操作符:
&&,||,!
v示例:
?awk -F: '$3>=0&&$3<=10{print "UID="$3"\t\t""username="$1}' /etc/passwd
[root@centos68 ~]# awk -F: '$3>=0&&$3<=10{print "UID="$3 "\t\t" "username=" $1}' /etc/passwd #當$3 大于等于0時,并且小于10時,打印$1 與 $3 UID=0 username=root UID=1 username=bin UID=2 username=daemon UID=3 username=adm UID=4 username=lp UID=5 username=sync UID=6 username=shutdown UID=7 username=halt UID=8 username=mail UID=10 username=uucp [root@centos68 ~]#
?awk -F: '$3==0 || $3>=500{printf "UID=%-7d username=%-10s\n",$3,$1}' /etc/passwd
[root@centos68 ~]# awk -F: '$3==0 || $3>=500{printf "UID=%-7d username=%-10s\n",$3,$1}' /etc/passwd #當$3等于0或者$3大于等于500,按格式打印$3 , 與$1 UID=0 username=root UID=65534 username=nfsnobody UID=500 username=admin UID=501 username=chen UID=502 username=mockbuild [root@centos68 ~]#
◎·函數調用:
function_name(argu1, argu2, …)
◎·條件表達式:
selector?if-true-expression:if-false-expression
#selector : 條件判斷
#if-true-expression : 條件為真的時候
#if-false-expression : 條件為假的時候
?示例:
awk -F: '{$3>=1000? usertype="CommonUser": usertype="SysadminorSysUser"; printf"%15s:%-s\n", $1,usertype}' /etc/passwd
#判斷 $3是否大于1000,如果大于1000,usertype變量賦值為:CommonUser,如果小于等于1000 usertype變量賦值為:SysadminorSysUser
[root@~]# awk -F: '{$3>=1000?Usertype="CommonUser":Usertype="SystemUser";printf"Usertype=%-s:Username:%-15sUID=%-d\n",Usertype,$1,$3 }' /etc/passwd Usertype=SystemUser: Username:root UID=0 Usertype=SystemUser: Username:bin UID=1 Usertype=SystemUser: Username:daemon UID=2 Usertype=SystemUser: Username:adm UID=3 Usertype=SystemUser: Username:lp UID=4 Usertype=SystemUser: Username:sync UID=5 Usertype=SystemUser: Username:shutdown UID=6 Usertype=SystemUser: Username:halt UID=7 Usertype=SystemUser: Username:mail UID=8 Usertype=SystemUser: Username:uucp UID=10 Usertype=SystemUser: Username:operator UID=11 Usertype=SystemUser: Username:games UID=12 Usertype=SystemUser: Username:gopher UID=13 Usertype=SystemUser: Username:ftp UID=14 Usertype=SystemUser: Username:nobody UID=99 Usertype=SystemUser: Username:dbus UID=81 Usertype=SystemUser: Username:usbmuxd UID=113 Usertype=SystemUser: Username:rpc UID=32 Usertype=SystemUser: Username:rtkit UID=499 Usertype=SystemUser: Username:avahi-autoipd UID=170 Usertype=SystemUser: Username:vcsa UID=69 Usertype=SystemUser: Username:abrt UID=173 Usertype=SystemUser: Username:rpcuser UID=29 Usertype=CommonUser: Username:nfsnobody UID=65534 Usertype=SystemUser: Username:haldaemon UID=68 Usertype=SystemUser: Username:ntp UID=38 Usertype=SystemUser: Username:apache UID=48 Usertype=SystemUser: Username:saslauth UID=498 Usertype=SystemUser: Username:postfix UID=89 Usertype=SystemUser: Username:mysql UID=27 Usertype=SystemUser: Username:gdm UID=42 Usertype=SystemUser: Username:pulse UID=497 Usertype=SystemUser: Username:sshd UID=74 Usertype=SystemUser: Username:tcpdump UID=72 Usertype=SystemUser: Username:admin UID=500 Usertype=SystemUser: Username:chen UID=501 Usertype=SystemUser: Username:mockbuild UID=502
◎·PATTERN:模式
·PATTERN:根據pattern條件,過濾匹配的行,再做處理
(1)如果未指定:空模式,匹配每一行
(2) /regular expression/:僅處理能夠模式匹配到的行,需要用/ /括起來
awk'/^UUID/{print $1}' /etc/fstab
awk'!/^UUID/{print $1}' /etc/fstab
[root@centos68 ~]# awk '/^UUID/{print}' /etc/fstab #顯示以UUID開頭的行 UUID=ca4c44c8-1c65-4896-a295-d55e5d5e5c5e / ext4 defaults 1 1 UUID=2c97fd2d-e455-493b-822c-25ce8c330e2b /boot ext4 defaults 1 2 UUID=1c6d09df-f7a1-4a72-b842-2b94063f38c7 /testdir ext4 defaults 1 2 UUID=ebd1d743-af4a-465b-98a3-6c9d3945c1d7 swap swap defaults 0 0 [root@centos68 ~]# awk '/UUID/{print}' /etc/fstab UUID=ca4c44c8-1c65-4896-a295-d55e5d5e5c5e / ext4 defaults 1 1 UUID=2c97fd2d-e455-493b-822c-25ce8c330e2b /boot ext4 defaults 1 2 UUID=1c6d09df-f7a1-4a72-b842-2b94063f38c7 /testdir ext4 defaults 1 2 UUID=ebd1d743-af4a-465b-98a3-6c9d3945c1d7 swap swap defaults 0 0
[root@centos68 ~]# awk '!/^UUID/{print}' /etc/fstab #顯示非UUID開頭的行 # # /etc/fstab # Created by anaconda on Tue Jul 19 18:10:17 2016 # # Accessible filesystems, by reference, are maintained under '/dev/disk' # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info # tmpfs /dev/shm tmpfs defaults 0 0 devpts /dev/pts devpts gid=5,mode=620 0 0 sysfs /sys sysfs defaults 0 0 proc /proc proc defaults 0 0 /dev/sda6 /mnt/sda6 ext4 defaults,usrquota,grpquota 0 0 [root@centos68 ~]#
(3) relational expression: 關系表達式;結果有“真”有“假”;結果為“真”才會被處理;
·真:結果為非0值,非空字符串
·假:結果為空字符串
·示例:
?awk –F: '$3>=1000{print $1,$3}' /etc/passwd
?awk -F: '$3<1000{print $1,$3}' /etc/passwd
?awk -F: '$NF=="/bin/bash"{print $1,$NF}' /etc/passwd
?awk -F: '$NF~/bash$/{print $1,$NF}' /etc/passwd
[root@centos68 ~]# awk -F: '$NF~"/bin/bash"{print$1,"\t",$NF}' /etc/passwd root /bin/bash mysql /bin/bash admin /bin/bash chen /bin/bash mockbuild /bin/bash [root@centos68 ~]# awk -F: '$NF~"bash$"{print$1,"\t",$NF}' /etc/passwd root /bin/bash mysql /bin/bash admin /bin/bash chen /bin/bash mockbuild /bin/bash [root@centos68 ~]#
?seq 10 | awk 'i=!i'
[root@centos68 ~]# seq 10 | awk 'i=!i{print}' 1 3 5 7 9 [root@centos68 ~]# seq 10 | awk 'i=!i' 1 3 5 7 9 [root@centos68 ~]#
(4) line ranges:行范圍(在模式之間匹配,或通過NR變量來判斷)
startline,endline:/pat1/,/pat2/不支持直接給出數字格式
awk-F: '/^root/,/^nobody/{print $1}' /etc/passwd
[root@centos68 ~]# awk -F: '/^bin/,/^mail/{print NR "\t" $1}' /etc/passwd 2 bin 3 daemon 4 adm 5 lp 6 sync 7 shutdown 8 halt 9 mail [root@centos68 ~]#
awk-F: '(NR>=2&&NR<=10){print $1}' /etc/passwd
[root@centos68 ~]# awk -F: '(NR>=2&&NR<=9){print NR"\t" $1 }' /etc/passwd 2 bin 3 daemon 4 adm 5 lp 6 sync 7 shutdown 8 halt 9 mail [root@centos68 ~]# awk -F: 'NR>=2&&NR<=10{print NR"\t" $1 }' /etc/passwd 2 bin 3 daemon 4 adm 5 lp 6 sync 7 shutdown 8 halt 9 mail 10 uucp
(5) BEGIN/END模式
BEGIN{}: 僅在開始處理文件中的文本之前執行一次
END{}:僅在文本處理完成之后執行一次
◎·PATTERN:模式事例
?awk -F : 'BEGIN {print "USER USERID"} {print $1":"$3} END{print "end file"}' /etc/passwd
[root@centos68 ~]# awk -F: 'BEGIN{print "USER \t USERID"}{print $1" \t "$3}END{print "end file"}' /etc/passwd USER USERID root 0 bin 1 daemon 2 adm 3 lp 4 sync 5 shutdown 6 halt 7 mail 8 uucp 10 operator 11 games 12 gopher 13 ftp 14 nobody 99 dbus 81 usbmuxd 113 rpc 32 rtkit 499 avahi-autoipd 170 vcsa 69 abrt 173 rpcuser 29 nfsnobody 65534 haldaemon 68 ntp 38 apache 48 saslauth 498 postfix 89 mysql 27 gdm 42 pulse 497 sshd 74 tcpdump 72 admin 500 chen 501 mockbuild 502 end file [root@centos68 ~]#
awk -F: 'BEGIN{print "USER \t USERID\n——————"}{print $1" \t "$3}END{print "===========\nend file"}' /etc/passwd
[root@centos68 ~]# awk -F: 'BEGIN{print "USER \t USERID\n------------------"}{print $1" \t "$3}END{print "===========\nend file"}' /etc/passwd USER USERID ------------------------ root 0 bin 1 daemon 2 adm 3 lp 4 sync 5 shutdown 6 halt 7 mail 8 uucp 10 operator 11 games 12 gopher 13 ftp 14 nobody 99 dbus 81 usbmuxd 113 rpc 32 rtkit 499 avahi-autoipd 170 vcsa 69 abrt 173 rpcuser 29 nfsnobody 65534 haldaemon 68 ntp 38 apache 48 saslauth 498 postfix 89 mysql 27 gdm 42 pulse 497 sshd 74 tcpdump 72 admin 500 chen 501 mockbuild 502 ================================ end file [root@centos68 ~]#
§·awk action (常用動作)
·常用的action分類
?(1) Expressions:算術,比較表達式等
?(2) Control statements:if, while等
?(3) Compound statements:組合語句
?(4) input statements
?(5) output statements:print等
§·awk條件判斷
※·awk控制語句
v? { statements;… } 組合語句
v? if(condition) {statements;…}
v? if(condition) {statements;…} else {statements;…}
v? while(conditon) {statments;…}
v? do {statements;…} while(condition)
v? for(expr1;expr2;expr3) {statements;…}
v? break
v? continue
v? delete array[index]
v? delete array
v? exit
※·awk控制語句if-else
語法:
if(condition) statement [else statement]
if(condition1){statement1}else if(condition2){statement 2}else{statement3}
v使用場景:對awk取得的整行或某個字段做條件判斷
v示例:
awk -F: '{if($3<=10)printf"Username=%-10s Uid=%d\n",$1,$3}' /etc/passwd
[root@centos68 ~]# awk -F: '{if($3<=10)printf"Username=%-10s Uid=%d\n",$1,$3}' /etc/passwd Username=root Uid=0 Username=bin Uid=1 Username=daemon Uid=2 Username=adm Uid=3 Username=lp Uid=4 Username=sync Uid=5 Username=shutdown Uid=6 Username=halt Uid=7 Username=mail Uid=8 Username=uucp Uid=10
awk -F: '{if($NF=="/bin/bash")print$1"\t" $NF}' /etc/passwd
[root@centos68 ~]# awk -F: '{if($NF=="/bin/bash")print$1"\t" $NF}' /etc/passwd root /bin/bash mysql /bin/bash admin /bin/bash chen /bin/bash mockbuild /bin/bash [root@centos68 ~]#
awk '{if(NF>6)print $0}' /etc/fstab
[root@centos68 ~]# awk '{if(NF>6)print $0}' /etc/fstab # Created by anaconda on Tue Jul 19 18:10:17 2016 # Accessible filesystems, by reference, are maintained under '/dev/disk' # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info [root@centos68 ~]#
awk-F: '{if($3>=1000) {printf"Common user: %s\n",$1} else {printf"root or Sysuser: %s\n",$1}}' /etc/passwd
[root@centos68 ~]# awk -F: '{if($3>=1000){printf"Common user:%s\n",$1}else{printf"root or Sysuser:%s\n",$1}}' /etc/passwd root or Sysuser:root root or Sysuser:bin root or Sysuser:daemon root or Sysuser:adm root or Sysuser:lp root or Sysuser:sync root or Sysuser:shutdown root or Sysuser:halt root or Sysuser:mail root or Sysuser:uucp root or Sysuser:operator root or Sysuser:games root or Sysuser:gopher root or Sysuser:ftp root or Sysuser:nobody root or Sysuser:dbus root or Sysuser:usbmuxd root or Sysuser:rpc root or Sysuser:rtkit root or Sysuser:avahi-autoipd root or Sysuser:vcsa root or Sysuser:abrt root or Sysuser:rpcuser Common user:nfsnobody root or Sysuser:haldaemon root or Sysuser:ntp root or Sysuser:apache root or Sysuser:saslauth root or Sysuser:postfix root or Sysuser:mysql root or Sysuser:gdm root or Sysuser:pulse root or Sysuser:sshd root or Sysuser:tcpdump root or Sysuser:admin root or Sysuser:chen root or Sysuser:mockbuild [root@centos68 ~]#
df -h|awk -F[%] '/^\/dev/{print $1} '|awk'{if($NF>=80) print $1}‘
[root@centos68 ~]# df -h | awk -F% '/^\/dev/{print $1}' #找出%前面的行 /dev/sda2 48G 21G 25G 46 /dev/sda1 190M 60M 117M 34 /dev/sda3 20G 122M 18G 1 /dev/sda6 9.8G 23M 9.2G 1 /dev/sr0 3.7G 3.7G 0 100 [root@centos68 ~]# df -h | awk -F% '/^\/dev/{print $1}'| awk '{if($NF>=80)print $1}' #找出大于%80的行 /dev/sr0 [root@centos68 ~]#
awk'BEGIN{ test=100;if(test>90){ print "very good";}else if(test>60){ print "good";}else{ print "no pass";}}'
[root@centos68 ~]# awk -F: 'BEGIN{test=50;if(test>90){print"very good"}else if(test>60){print "good"}else{print"no pass"}}' no pass [root@centos68 ~]# awk -F: 'BEGIN{test=70;if(test>90){print"very good"}else if(test>60){print "good"}else{print"no pass"}}' good [root@centos68 ~]# awk -F: 'BEGIN{test=93;if(test>90){print"very good"}else if(test>60){print "good"}else{print"no pass"}}' very good [root@centos68 ~]#
※·awk控制語句 while循環
·while循環
·語法:while(condition) statement
條件“真”,進入循環;條件“假”,退出循環
·使用場景:
對一行內的多個字段逐一類似處理時使用
對數組中的各元素逐一處理時使用
·示例:length()求出該字段的長度 函數調用
awk '/^UUID/{i=1;while(i<=NF){printf"%-50s %-5d\n",$i ,length($i);i++}}' /etc/fstab
#找出UUID開頭的行,并且把每個字段分別統計字符個數
[root@centos68 ~]# awk '/^UUID/{i=1;while(i<=NF){printf"%-50s %-5d\n",$i ,length($i);i++}}' /etc/fstab UUID=ca4c44c8-1c65-4896-a295-d55e5d5e5c5e 41 / 1 ext4 4 defaults 8 1 1 1 1 UUID=2c97fd2d-e455-493b-822c-25ce8c330e2b 41 /boot 5 ext4 4 defaults 8 1 1 2 1 UUID=1c6d09df-f7a1-4a72-b842-2b94063f38c7 41 /testdir 8 ext4 4 defaults 8 1 1 2 1 UUID=ebd1d743-af4a-465b-98a3-6c9d3945c1d7 41 swap 4 swap 4 defaults 8 0 1 0 1
awk '/^UUID/{i=1;while(i<=NF){if(length($i)>=8){ printf"%-50s %-5d\n",$i ,length($i)};i++}}' /etc/fstab
#找出UUID開頭的行,當字段數量大于8時,顯示字段數和字符數量
[root@centos68 ~]# awk '/^UUID/{i=1;while(i<=NF){if(length($i)>=8){ printf"%-50s %-5d\n",$i ,length($i)};i++}}' /etc/fstab UUID=ca4c44c8-1c65-4896-a295-d55e5d5e5c5e 41 defaults 8 UUID=2c97fd2d-e455-493b-822c-25ce8c330e2b 41 defaults 8 UUID=1c6d09df-f7a1-4a72-b842-2b94063f38c7 41 /testdir 8 defaults 8 UUID=ebd1d743-af4a-465b-98a3-6c9d3945c1d7 41 defaults 8 [root@centos68 ~]#
※·awk控制語句 do ….. while循環
?do-while循環
語法:do statement while(condition)
意義:無論真假,至少執行一次循環體
?示例:
?awk 'BEGIN{ total=0;i=0;do{ total+=i;i++;}while(i<=100);print total}'
#與while循序的不同之處在于,do先執行一次循序體,在通過while條件判斷是否需不需要執行循環體
[root@centos68 ~]# awk 'BEGIN{total=0;i=0;do{total+=i;i++}while(i<=100);print total}' 5050 [root@centos68 ~]#
※·awk控制語句 for 循環
for循環
語法:for(expr1;expr2;expr3) statement
for(variable assignment;condition;iterationprocess) {for-body}
#for (變量賦值;判斷條件;變量修正){循序體}
特殊用法:能夠遍歷數組中的元素;
語法:for(var in array) {for-body}
示例:
awk '/^UUID/{for(i=1;i<=NF;i++){if(length($i)>8){print $i,length($i)}}}' /etc/fstab
[root@centos68 ~]# awk '/^UUID/{for(i=1;i<=NF;i++){if(length($i)>8){print $i,length($i)}}}' /etc/fstab UUID=ca4c44c8-1c65-4896-a295-d55e5d5e5c5e 41 UUID=2c97fd2d-e455-493b-822c-25ce8c330e2b 41 UUID=1c6d09df-f7a1-4a72-b842-2b94063f38c7 41 UUID=ebd1d743-af4a-465b-98a3-6c9d3945c1d7 41
※·性能比較
v#time (awk 'BEGIN{ total=0;for(i=0;i<=10000;i++){total+=i;};print total;}')
[root@centos68 ~]# time(awk 'BEGIN{total=0;for(i=0;i<=1000;i++){total+=i};print total}') 500500 real 0m0.018s user 0m0.000s sys 0m0.017s [root@centos68 ~]#
v#time(total=0;for i in $(seq 10000);do total=$(($total+i));done;echo $total)
[root@centos68 ~]# time(total=0;for i in $(seq 10000);do total=$(($total+i));done ;echo $total) 50005000 real 0m0.091s user 0m0.073s sys 0m0.030s
※·awk控制語句 switch語句
?switch語句
語法:switch(expression) {case VALUE1 or /REGEXP/: statement; case VALUE2 or /REGEXP2/: statement; …; default: statement}
?break和continuevbreak [n]vnextvcontinue [n]
vnext 提前結束對本行處理而直接進入下一行處理(awk自身循環)
?awk‘BEGIN{sum=0;for(i=1;i<=100;i++){if(i%2==0){continue}sum+=i}print sum}‘
#統計1-100偶數的和 [root@Centos7 ~]# awk 'BEGIN{sum=0;for(i=1;i<=100;i++){if(i%2==0){continue}sum+=i};print sum}' 2500 #統計1-100奇數的和 [root@Centos7 ~]# awk 'BEGIN{sum=0;for(i=1;i<=100;i++){if(i%2!=0){continue}sum+=i};print sum}' 2550 [root@Centos7 ~]#
?awk‘BEGIN{sum=0;for(i=1;i<=100;i++){if(i==11){break}sum+=i}print sum}‘
#統計1-10的和
[root@Centos7 ~]# awk 'BEGIN{sum=0;for(i=1;i<=100;i++){if(i==11){break}sum+=i};print sum}' 55 [root@Centos7 ~]#
?awk -F: '{if($3%2!=0)next;printf"Username: %-15s Uid: %d\n",$1,$3}' /etc/passwd
#顯示UID號為偶數的行
[root@Centos7 ~]# awk -F: '{if($3%2!=0)next;printf"Username: %-15s Uid: %d\n",$1,$3}' /etc/passwd Username: root Uid: 0 Username: daemon Uid: 2 Username: lp Uid: 4 Username: shutdown Uid: 6 Username: mail Uid: 8 Username: games Uid: 12 Username: ftp Uid: 14 Username: systemd-network Uid: 998 Username: unbound Uid: 996 Username: geoclue Uid: 994 Username: rpc Uid: 32 Username: rtkit Uid: 172 Username: avahi-autoipd Uid: 170 Username: setroubleshoot Uid: 992 Username: nfsnobody Uid: 65534 Username: libstoragemgmt Uid: 990 Username: gdm Uid: 42 Username: avahi Uid: 70 Username: sshd Uid: 74 Username: ntp Uid: 38 Username: tcpdump Uid: 72 Username: ChenJiaShun Uid: 1000 Username: hacker Uid: 1002
§·awk數組
◎·關聯數組:array [index-expression]
◎·index-expression:
?(1) 可使用任意字符串;字符串要使用雙引號括起來
?(2) 如果某數組元素事先不存在,在引用時,awk會自動創建此元素,并將其值初始化為“空串”
?若要判斷數組中是否存在某元素,要使用“index in array”格式進行遍歷
◎·示例:
?weekdays[“mon”]="Monday“
?awk 'BEGIN{weekdays["mon"]="Monday";
?weekdays["tue"]="Tuesday";print weekdays["mon"]}‘
awk '!a[$0]++{print NR , $1}' aaaa
#排除重復行 #分析 a[$0]默認情況下為空,空及為0,$0表示為整行, #awk為行間自動循環,比如第一行為:a[a]=0(空), !a[a]=1(非空),非空就打印出 aaaa文件的整行及 其行號 a[a]++及是,a[a]=2 #比如第二行為:a[b]=0(空), !a[b]=1(非空),非空就打印出 aaaa文件的整行; #當遇到第7行 $0=b,時,a[$0]=1 , !a[$0]=0 ,不在打印,a[$0]++ , a[$0]=1. [root@Centos7 ~]# awk '!a[$0]++{print NR , $1}' aaaa 1 a 2 b 3 c 4 d 5 e 6 aa 9 ee [root@Centos7 ~]# awk '{print NR , $1}' aaaa 1 a 2 b 3 c 4 d 5 e 6 aa 7 d 8 c 9 ee [root@Centos7 ~]#
◎·若要遍歷數組中的每個元素,要使用for循環
◎·for(varin array) {for-body}
◎·注意:var會遍歷array的每個索引
◎·示例:
?awk 'BEGIN{week["mon"]="monday";week["tue"]="tueday";week["ser"]="serday";for(i in week){print i ,week[i]}}'
[root@Centos7 ~]# awk 'BEGIN{week["mon"]="monday";week["tue"]="tueday";week["ser"]="serday";for(i in week){print i ,week[i]}}' # 開始給變量給數組week 賦值 week["mon"]="monday";week["tue"]="tueday";week["ser"]="serday # for( i in week) 變量i在數組 week中遍歷,取得week的索引號, # {print i ,week[i]} 打印顯示 變量i的值和 week[i] 的值 tue tueday ser serday mon monday [root@Centos7 ~]#
?netstat -tan | awk '/^tcp/{ state[$NF]++ }END{for ( i in state ){ print i ,state[i] }}'
[root@Centos7 ~]# netstat -tan | awk '/^tcp/{ state[$NF]++ }END{for ( i in state ){ print i ,state[i] }}' LISTEN 12 ESTABLISHED 3 #查看正常情況下的 netstat -tan 的情況 # /^tcp/ : 匹配以tcp開頭的行, # { state[$NF]++ } : 統計最后一個字段的數量分組及其數量統計 # for ( i in state ){ print i ,state[i]} : [root@Centos7 ~]# netstat -tan Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 192.168.122.1:53 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN tcp 0 0 127.0.0.1:6010 0.0.0.0:* LISTEN tcp 0 0 127.0.0.1:6011 0.0.0.0:* LISTEN tcp 0 52 10.1.16.70:22 10.1.16.1:60325 ESTABLISHED tcp 0 0 10.1.16.70:22 10.1.16.1:59953 ESTABLISHED tcp 0 0 10.1.16.70:22 10.1.16.1:56490 ESTABLISHED tcp6 0 0 :::80 :::* LISTEN tcp6 0 0 :::22 :::* LISTEN tcp6 0 0 ::1:631 :::* LISTEN tcp6 0 0 ::1:25 :::* LISTEN tcp6 0 0 ::1:6010 :::* LISTEN tcp6 0 0 ::1:6011 :::* LISTEN tcp6 0 0 10.1.16.70:80 10.1.16.1:60795 FIN_WAIT2 tcp6 0 0 10.1.16.70:80 10.1.16.1:60873 FIN_WAIT2 tcp6 0 0 10.1.16.70:80 10.1.16.1:60889 FIN_WAIT2 tcp6 0 0 10.1.16.70:80 10.1.16.1:60794 FIN_WAIT2 tcp6 0 0 10.1.16.70:80 10.1.16.1:60785 TIME_WAIT tcp6 0 0 10.1.16.70:80 10.1.16.1:60845 FIN_WAIT2 tcp6 0 0 10.1.16.70:80 10.1.16.1:60887 FIN_WAIT2 tcp6 0 0 10.1.16.70:80 10.1.16.1:60847 FIN_WAIT2 tcp6 0 0 10.1.16.70:80 10.1.16.1:60888 FIN_WAIT2 tcp6 0 0 10.1.16.70:80 10.1.16.1:60872 FIN_WAIT2 tcp6 0 0 10.1.16.70:80 10.1.16.1:60848 FIN_WAIT2 tcp6 0 0 10.1.16.70:80 10.1.16.1:60886 FIN_WAIT2 tcp6 0 0 10.1.16.70:80 10.1.16.1:60793 FIN_WAIT2 tcp6 0 0 10.1.16.70:80 10.1.16.1:60796 FIN_WAIT2 tcp6 0 0 10.1.16.70:80 10.1.16.1:60849 FIN_WAIT2 tcp6 0 0 10.1.16.70:80 10.1.16.1:60869 FIN_WAIT2
?awk '{ip[$1]++}END{for(iin ip) {print i,ip[i]}}' /var/log/httpd/access_log
[root@Centos7 ~]# awk '/^[[:digit:]]/{logs[$1]++}END{for( i in logs ){printf"Access IP: %-10s Count: %-3d\n",i,logs[i]}}' /var/log/httpd/access_log # 統計訪問網站IP地址統計 # /^[[:digit:]]/{logs[$1]++} : 匹配以數字開頭,申明變量保存第一段的是IP地址數量統計。 # for( i in logs ) :讓 i 取得logs數組中 索引號(索引號即為IP) # 按格式打印 IP地址 與 訪問次數的統計 Access IP: 10.1.44.44 Count: 9 Access IP: 10.1.16.61 Count: 9 Access IP: 10.1.16.1 Count: 49 [root@Centos7 ~]#
§·awk內建函數
數值處理:
rand():返回0和1之間一個隨機數
awk'BEGIN{srand(); for (i=1;i<=10;i++)print int(rand()*100) }'
字符串處理:
?length([s]):返回指定字符串的長度
?sub(r,s,[t]):對t字符串進行搜索r表示的模式匹配的內容,并將第一個匹配的內容替換為s
echo "2008:08:08 08:08:08" | awk'sub(/:/,“-",$1)'
?gsub(r,s,[t]):對t字符串進行搜索r表示的模式匹配的內容,并全部替換為s所表示的內容
echo "2008:08:08 08:08:08" | awk‘gsub(/:/,"",$1)'
?split(s,array,[r]):以r為分隔符,切割字符s,并將切割后的結果保存至array所表示的數組中,
第一個索引值為1,第二個索引值為2,…
?awk 'BEGIN{srand();for(i=1;i<=10;i++){printf"Rand :%-1.8f Rand init:%-10d\n", rand() ,int(rand()*100)}}'
[root@Centos7 dev]# awk 'BEGIN{srand();for(i=1;i<=10;i++){printf"Rand :%-1.8f Rand init:%-10d\n", rand() ,int(rand()*100)}}' # srand() 是一個函數,rand()只用通過srand()函數的出現才可以正常的工作,生成0-1之間的隨機數 #生成10個隨機數 Rand :0.18251386 Rand init:11 Rand :0.19172835 Rand init:38 Rand :0.25055455 Rand init:64 Rand :0.48638138 Rand init:55 Rand :0.21168378 Rand init:63 Rand :0.17734465 Rand init:9 Rand :0.36041239 Rand init:83 Rand :0.57846720 Rand init:30 Rand :0.17588418 Rand init:28 Rand :0.01415744 Rand init:34 [root@Centos7 dev]#
?netstat -tan | awk '/^tcp/{split($5,ip,":");count[ip[1]]++;print $5}END{{print "========="}for( i in count ){ print i, count[i]}}'
[root@]# netstat -tan | awk '/^tcp/{split($5,ip,":");count[ip[1]]++;print $5}END{{print "========="}for( i in count ){ print i, count[i]}}' # {split($5,ip,":") :把netstat -tan 的第五段取出來,并以 : 為分隔符,把每段保存在數組 ip中, # 處理第1行時 : ip[1]= 0.0.0.0 ip[2]= * 處理第1行時 : count[0.0.0.0]=1 #處理第2行時: ip[1]= 0.0.0.0 ip[2]= * 處理第2行時:count[0.0.0.0]=2 #處理第7行時:ip[1]= 10.1.16.1 ip[2]= 60325 處理第7行時: count[10.1.16.1]=1 #處理第8行時:ip[1]=(空) ip[2]=(空) ip[3]=(空) ip[2]=* (由于第8行分號較多,分隔成的索引號有4個) 處理第8行時:count[(空)]=1 0.0.0.0:* 0.0.0.0:* 0.0.0.0:* 0.0.0.0:* 0.0.0.0:* 10.1.16.1:60325 :::* :::* :::* :::* :::* ========= 5 0.0.0.0 5 10.1.16.1 1 [root@Centos7 dev]#
§·awk自建函數
自定義函數
格式:
function name ( parameter, parameter, ... ) { statements return expression }
示例:
#cat fun.awk function max(v1,v2) { v1>v2?var=v1:var=v2 return var } BEGIN{a=3;b=2;print max(a,b)}
#awk –f fun.awk
§·調用系統命令
※·awk中調用shell命令
system命令
空格是awk中的字符串連接符,如果system中需要使用awk中的變量可以使用空格分隔,或者說除了awk的變量外其他一律用""引用起來。
awk BEGIN'{system("hostname") }'
awk'BEGIN{score=100; system("echo your score is " score) }'
※·awk腳本
將awk程序寫成腳本,直接調用或執行
示例:
#cat f1.awk
if($3>=1000)print $1,$3}
#awk -F: -f f1.awk /etc/passwd
#cat f2.awk
#!/bin/awk –f
#this is a awk script
{if($3>=1000)print $1,$3}
#chmod +x f2.awk
#f2.awk –F: /etc/passwd
※·向awk腳本傳遞參數
格式:
awkfile var=value var2=value2… Inputfile
示例:
#cat test.awk #!/bin/awk –f {if($3 >=min && $3<=max)print $1,$3}
#chmod +x test.awk
#test.awk -F: min=100 max=200 /etc/passwd
§·練習
1、兩個文件的內容如下,使用awk以后,寫出輸出后的文件內容
file1
1:beijing:1322676:::
2:shanghai:222676:::
3:guangdong:342676:::
file2
1:x:d3dn1
2:y:DWHh0
3:z:hWX9Y
awk 'BEGIN{OFS=FS=":"}NR==FNR{a[$1]=$2;}NR>FNR{$2=a[$1];print} file1 file2
[root@localhost ~]# awk 'BEGIN{OFS=FS=":"}NR==FNR{a[$1]=$2;}NR>FNR{$2=a[$1];print}' file1 file2 #分析 BEGIN{OFS=FS=":"} 定義文件分隔符為 : ,定義輸出字段分隔符為 : #NR==FNR{a[$1]=$2;} 當NR==FNR時,數組 a[$1]=$2,即使file1文件中,a[1]=beijing,a[2]=shanghai,a[3]=guangdong #NR>FNR{$2=a[$1] 當NR>FNR時,即是在file2中,$2=a[$1],即是:x=beijing ,y=shanghai,z=guangdong 1:beijing:d3dn1 2:shanghai:DWHh0 3:guangdong:hWX9Y [root@localhost ~]#
2、統計/etc/fstab文件中每個文件系統類型出現的次數
awk '/^[^#]/{a[$3]++}END{for( i in a ){printf"filesystem is :%-7s count : %-5d\n",i,a[i]}}' fstab.bak
[root@localhost ~]# awk '/^[^#]/{a[$3]++}END{for( i in a ){printf"filesystem is :%-7s count : %-5d\n",i,a[i]}}' fstab.bak filesystem is :swap count : 5 filesystem is :ext4 count : 5 filesystem is :xfs count : 5
3、統計/etc/fstab文件中每個單詞出現的次數;
awk '{for(i=1;i<=NF;i++){count[$i]++}}END{for(i in count) {print i,count[i]}}' fstab.bak
[root@localhost ~]# awk '{for(i=1;i<=NF;i++){count[$i]++}}END{for(i in count) {print i,count[i]}}' fstab.bak man 1 and/or 1 maintained 1 UUID=d0e00dc6-365b-48e7-8ec4-1c06970d2b89 5 xfs 5 /dev/mapper/centos-root 5 UUID=60a26f51-d413-4acc-94ff-5573f8ad3a59 5 14 1 Accessible 1 # 7 Thu 1 are 1 defaults 15 blkid(8) 1 / 5 0 20 See 1 1 5 2 5 Created 1 on 1 mount(8) 1 ext4 5 anaconda 1 fstab(5), 1 /boot 5 00:13:05 1 findfs(8), 1 2016 1 '/dev/disk' 1 by 2 /etc/fstab 1 pages 1 more 1 info 1 swap 10 Jul 1 filesystems, 1 reference, 1 for 1 under 1 [root@localhost ~]#
原創文章,作者:linux_root,如若轉載,請注明出處:http://www.www58058.com/47932
awk是一個很方便的文本格式化工具,這也是以后面試題必會遇到的面試題,希望下來多加練習,熟練掌握,