awk
-v設置變量
-F 指定分隔符
內置變量
FS:輸入字段分隔符,默認為空白字符,讀入內容的分隔符
OFS:輸出字段的分隔符
RS:指定行(記錄)分隔符
ORS:輸出記錄分隔符
NF:字段數量
NR:記錄的數量
ARGC:命令行參數的個數
ARGV:數組,保存的是命令行所有的參數
例1:不依賴文件和標準輸入
[root@centos7 ~]#awk ‘BEGIN{print “haha”}’
haha
BEGIN表示只處理一次,后面可以不處理文件
例2:做數值運算
[root@centos7 ~]#awk ‘BEGIN{print 2^10}’
1024
例3:打印/etc/passwd文件中的用戶名和uid,輸出以:號做分隔符
[root@centos7 ~]#awk -F: ‘{print $1″:”$3}’ /etc/passwd
root:0
bin:1
daemon:2
指定輸入分隔符
awk -v FS=: ‘{print $1FS$3}’ /etc/passwd
FS是awk里的變量,
[root@centos7 ~]#fs=”:”;awk -v FS=$fs ‘{print $1FS$3}’ /etc/passwd
指定輸入和輸出分隔符
[root@centos7 ~]#fs=”:”;awk -v FS=$fs -v OFS=: ‘{print $1,$3}’ /etc/passwd
例:取分區名和利用率
[root@centos7 data]#df | grep ^/dev/sd | awk -v FS=”%” ‘{print $1}’ | awk ‘{print $1,$5}’
/dev/sda2 37
/dev/sda3 3
/dev/sda1 16
例:NF字段數量
[root@centos7 data]#awk -v FS=”:” ‘{print NF,$NF}’ /etc/passwd
7 /sbin/nologin
7 /bin/bash
7 /bin/bash
例: 打印倒數第二個字段
[root@centos7 data]#awk -v FS=”:” ‘{print $(NF-1)}’ /etc/passwd
/root
/bin
/sbin
/var/adm
/var/spool/lpd
/sbin
/sbin
/sbin
例:NR記錄數量
[root@centos7 ~]#awk -v FS=”:” ‘{print NR,$1}’ /etc/passwd
1 root
2 bin
3 daemon
4 adm
5 lp
6 sync
awk -v FS=”:” ‘{print NR,$1}’ /etc/passwd /etc/fstab 假如處理的是兩個文件,那么他們記錄數量方式是一起編號
awk -v FS=”:” ‘{print FNR,$1}’ /etc/passwd /etc/fstab 則各自有各自的編號
例:參數的個數ARGC
[root@centos7 ~]#awk ‘{print ARGC}’ /etc/passwd /etc/inittab
3
3
3
3
例:數組ARGV
[root@centos7 ~]#awk ‘{print ARGV[1]}’ /etc/issue /etc/fstab
/etc/issue
/etc/issue
/etc/issue
/etc/issue
/etc/issue
/etc/issue
awk變量自定義變量
定義方式
1.-v var=value
[root@centos7 ~]#awk -v name=wang ‘BEGIN{print name}’
wang
2.在program中直接定義
[root@centos7 ~]#awk ‘BEGIN{name=”wang”;print name}’
wang
例:-f調用文件
[root@centos7 data]#cat scripts
{print $1,$3}
[root@centos7 data]#awk -v FS=”:” -v OFS=”=” -f /data/scripts /etc/passwd
root=0
bin=1
daemon=2
adm=3
lp=4
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
[root@centos7 data]#awk -F: ‘BEGIN{print “user??? ??????????????????????uid\n———————————–“}{printf “%-20s:%10d\n”,$1,$3}END{print “———————————–“}’ /etc/passwd
模式匹配符:
~:左邊是否和右邊匹配包含 !~:是否不匹配
示例:
awk –F: ‘$0 ~ /root/{print $1}‘ /etc/passwd
awk ‘$0~“^root”‘ /etc/passwd
awk ‘$0 !~ /root/‘ /etc/passwd
awk –F: ‘$3==0’ /etc/passwd
例:顯示用戶id號大于1000小于1010的用戶名和id
[root@centos7 data]#awk -F: ‘$3>=1000 && $3<=1010{print $1,$3}’ /etc/passwd
wang 1000
bash 1001
testbash 1002
basher 1003
sh 1004
nologin 1005
haha 1006
hehe 1007
aa 1008
bb 1009
feng 1010
例:取反
[root@centos7 data]#awk -F: ‘! ($3>=1000){print $1,$3}’ /etc/passwd
在awk中1為真,0為假
[root@centos7 data]#awk ‘BEGIN{print !i}’
1
[root@centos7 data]#awk ‘BEGIN{i=0;print !i}’
1
[root@centos7 data]#awk ‘BEGIN{i=2;print !i}’
0
[root@centos7 data]#awk ‘BEGIN{i=”abc”;print !i}’
0
awk控制語句if-else
語法:if(condition){statement;…}[else statement]
if(condition2){statement1}else if(condition2){statement2}else{statement3}
例:打印shell為/sbin/nologin的用戶
[root@centos6 data]#awk -v FS=: ‘{if($NF == “/sbin/nologin”)print $1}’ /etc/passwd
bin
daemon
adm
lp
例2:
awk ‘BEGIN{ test=100;if(test>90){print “very good“}else if(test>60){ print “good”}else{print “no pass”}}’
awk控制語句
語法:while(condition){statement;…}
使用場景:
對一行內的各個字段逐一類似處理時使用
對數組中的各元素逐一處理時使用
例:打印某行單詞,和字符長度
[root@centos6 data]#awk ‘/^[[:space:]]+kernel.*/{i=1;while(i<=NF){print $i,length($i);i++}}’ /etc/grub.conf
kernel 6
/vmlinuz-2.6.32-696.el6.x86_64 30
ro 2
root=UUID=50e87f34-5611-4315-9a53-21afd7fd859a 46
rd_NO_LUKS 10
rd_NO_LVM 9
LANG=en_US.UTF-8 16
rd_NO_MD 8
SYSFONT=latarcyrheb-sun16 25
length($i)表示變量$i字符的長度
例2:
[root@centos6 data]#awk ‘/^[[:space:]]+kernel.*/{i=1;while (i<=NF){if(length($i)>=10){print $i,length($i)};i++}}’ /etc/grub.conf
/vmlinuz-2.6.32-696.el6.x86_64 30
root=UUID=50e87f34-5611-4315-9a53-21afd7fd859a 46
rd_NO_LUKS 10
LANG=en_US.UTF-8 16
SYSFONT=latarcyrheb-sun16 25
crashkernel=auto 16
KEYBOARDTYPE=pc 15
KEYTABLE=us 11
(hd0,0)/vmlinuz-2.6.32-696.el6.x86_64 37
root=/dev/sda2 14
awk控制語句do-while循環
語法:do{statement;…}while(condition)
意義:無論真假,至少執行一次循環體
?
示例:
awk ‘BEGIN{ total=0;i=0;do{ total+=i;i++;}while(i<=100);print total}’
?
?awk控制語句for循環
語法:for(expr1;expr2;expr3{statement}
例1:
[root@centos6 data]#time awk ‘BEGIN{for(i=1;i<=100000000;i++)sum=sum+i;print sum}’
5000000050000000
real 0m9.548s
user 0m9.548s
sys?? 0m0.003s
time命令,測試awk性能
break和continue
awk ‘BEGIN{sum=0;for(i=1;i<=100;i++){if(i%2==0)continue;sum+=i}print sum}‘
awk ‘BEGIN{sum=0;for(i=1;i<=100;i++){if(i==66)break;sum+=i}print sum}‘
next:
提前結束對本行處理而直接進入下一行處理(awk自身循環)
awk -F: ‘{if($3%2!=0) next; print $1,$3}’ /etc/passwd
?[root@centos6 data]#awk -F: ‘{if($3>10 && $3<20)print $1,$3}’ /etc/passwd
operator 11
games 12
gopher 13
ftp 14
?
?awk數組
關聯數組:array[index-expression]
?index-expression:
(1) 可使用任意字符串;字符串要使用雙引號括起來
(2) 如果某數組元素事先不存在,在引用時,awk會自動創建此元素,并將其值初始化為“空串”,若要判斷數組中是否存在某元素,要使用“index in array”格式進行遍歷
若要遍歷數組中的每個元素,要使用for循環
for(var in array) {for-body}
注意:var會遍歷array的每個索引
例1:
[root@centos7~]#awk’BEGIN{name[“haha”]=”wang”;name[“hehe”]=”zhao”;name[“heihei”]=”zhang”;for(i in name)print name[i] }’
zhao
zhang
wang
ab -c 100 -n 2000 http://192.168.67.130/并發訪問
例:
[root@centos7 ~]#netstat -tan | awk ‘/^tcp/{state[$NF]++}END{for(i in state){print i,state[i]}}’
LISTEN 9
ESTABLISHED 1
TIME_WAIT 1999
例:
[root@centos7 ~]#cat /var/log/httpd/access_log | awk ‘/^[0-9]+/{ip[$1]++}END{for (i in ip){print i,ip[i]}}’
172.20.109.152 10
192.168.67.132 4004
列:把訪問量大于1000的IP放入防火墻
[root@centos7 data]#awk ‘/^[0-9]/{ip[$1]++}END{for(i in ip){if(ip[i]>1000)print i}}’ /var/log/httpd/access_log | while read ip;do iptables -A INPUT -s $ip -j REJECT;done
例:統計一個文件的單詞數
[root@centos7 data]#awk ‘{for(i=1;i<=NF;i++){word[$i]++}}END{for(j in word)print j,word[j]}’ /etc/fstab
本文來自投稿,不代表Linux運維部落立場,如若轉載,請注明出處:http://www.www58058.com/99070