AWK三劍客之一

筆記

timg

AWK
文本三劍客之一
awk ‘BEGIN{print “hello”}` 執行第一步不讀取文件。只打印hello

awk -F: ‘{print $1,$3}’ /etc/passwd
讀取/etc/passwd 以-F :為分隔符 打印 $1,$3 以空格隔開

df |awk ‘{print $1,$5}’
讀取df命令,因為分隔符是空格所有不用指定,打印的1列的第5列

################################################################################################################
AWK支持變量,分為內部變量和自定義變量
內部變量
列的分隔符
FS 是輸入的變量
例: awk -v FS=: ‘{print $1,$2}’ /etc/passwd 以空格為分隔符
例: awk -v FS=: ‘{print $1FS$2}’ /etc/passwd 調用命令以變量FS的:為分隔符
OFS 為輸出的分隔符
例: awk -v FS=: -v OFS=: ‘{print $1F,$2}’ /etc/passwd 以OSF指定的:為分隔符

RS行的分隔符
例: awk -v RS=” ” ‘{print $1,$2}’ /etc/passwd 以變量RS定義的空格為分隔符,打印第一行和第二行
例: awk -v ORS=”===” ‘{print}’ /etc/passwd 以變量ORS定義的輸出===為分隔符

NF 查看以分隔符隔開的字段有幾個
例:awk -v FS=”:” ‘{print NF}’ /etc/passwd
$NF 顯示最后一個字段
例:awk -v FS=”:” ‘{print $NF}’ /etc/passwd
$(NF-1) 顯示倒數第2個字段
例:awk -v FS=”:” ‘{print $(NF-1)}’ /etc/passwd
例:ls /mnt/cdrom/Packages/ |awk -v FS=”.” ‘{print $(NF-1)}’ |sort |uniq -c

NR 加編號,如果有多個文件,默認編號加一起
例: awk -v FS=”:” ‘{print NR,$0}’ /etc/passwd 給每一行的行首加一個編號
FNR 如果有多個文件,分開加編號
例:awk -v FS=”:” ‘{print FNR,$0}’ /etc/passwd /etc/fstab

FILENAME 在輸出的結果前叫文件名字
例:awk -v FS=”:” ‘{print FILENAME,$0}’ /etc/passwd /etc/fstab
**********************************************************************************************************************
自定義變量
awk -v test=”hello,wak” ‘{print test,$1}’ /etc/passwd
自定義一個test的變量 在文件的每一行前加變量

awk -v test=”hello,wak” ‘BEGIN{print test}’
BEGIN 不執行文件,只執行第一次
awk ‘BEGIN{test=”hello.awk”;print test}’
awk -v FS=: -v OFS=: ‘{var=”name”;print var,$1}’ /etc/passwd

##########################################################################################################################3###########################3
printf
printf不會自動換行得加\n
awk -F: ‘BEGIN{print “user uid\n——————————–“}{printf “%-20s:%10d\n”,$1,$2}’ /etc/passwd
打印文件的第1列和第3列,
第一列%-20s -字符靠左。后面有20個空格
中間用:分隔
第3例%10d默認靠右,字符前面有10個空格
printf不會自動換行得加\n
BEGIN 打印表頭
第一列的表頭是user ,第三列的表頭是uid
\n——————————– 在下一行顯示-

做一個列表
#!/bin/bash
#
#********************************************************************
#Author: zhouyafei
#Date: 2018-05-10
#FileName: s1.sh
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
#%-5s,-是左對齊,左對齊寬度為5的字符串 ,如果不加-默認右對齊
#%-4.2f:.2是保留兩位小數點
# \n 是換行符
printf “%-5s %-10s %-4s\n” NO Name Mark
printf “%-5s %-10s %-4.2f\n” 1 Sarath 80.3456
printf “%-5s %-10s %-4.2f\n” 2 James 90.787687
printf “%-5s %-10s %-4.2f\n” 3 Sarath 70.09987

awk ‘BEGIN{i=0;print ++i,i}’
++i是先相加在執行print打印 結果是 1 1

awk ‘BEGIN{i=0;print i++,i}’
i++ 先執行print打印i的值,在相加 。結果是0 1

#########################################################################################################################

操作符 左邊是否和右邊符合
格式是 $0 ~ / /
awk -F: ‘$0 ~ /root/{print $0}’ /etc/passwd
-F: 以:為分隔符
$0 ~ /root/ 顯示包含root的行
{print $0} 一行全部顯示

awk ‘$0 ~ /^root/’ /etc/passwd
代表默認打印{print $0}

awk -F: ‘$0 !~ /root/{print $0}’ /etc/passwd
$0 !~ /root/ 顯示不包含root的行
{print $0} 一行全部顯示

awk -F: ‘$0 ~ /^root/{print $0}’ /etc/passwd
/^root/顯示以root開頭的行 ^在正則表達式中的意思是開頭 $在正則表達式的意思是行尾
{print $0} 一行全部顯示

df -h |awk -v FS=” ” ‘$0 ~ /^\/dev\/sd/{print $1,$5}’
-v FS=” ” 代表分隔符為空格,也可以用-F“ ”代表,也可以不寫
$0 ~ /^\/dev\/sd/ 代表/dev/da開同的行 ,因為是正則表達式所有得加轉義符,轉到原來的意思
{print $1,$5} 代表現在第一列和第五列

#####################################################################################################################################################

可以顯示大于多少,小于多少 ,等于多少,大于等于多少,小于等于多少
df -h |awk -v FS=”%” ‘$0 ~ /^\/dev\/sd/{print $1}’ |awk ‘$5>=10’
-v FS=”%” 以百分號為分隔符
$0 ~ /^\/dev\/sd/代表/dev/da開同的行 ,因為是正則表達式所有得加轉義符,轉到原來的意思
{print $1} 顯示以百分號為分隔符,以/dev/da開頭的行
$5>=10 $5顯示第5列 大于等于10的行
df -h |awk -v FS=”%” ‘$0 ~ /^\/dev\/sd/{print $1}’ |awk ‘$5>=10{print $1,$5}’

awk -F: ‘$3>=1000 && $3<=1010’ /etc/passwd
-F: 以:為分隔符
$3>=1000 第三列大于等于1000
&& 代表和
$3<=1010 第三列小于等于1010

取反
awk -F: ‘ ! ($3>=1000) ‘ /etc/passwd
‘ ! ($3>=1000) ‘ 顯示不是大于等于1000的數字

awk ‘BEGIN{print 1+1}’ 相加

awk ‘BEGIN{print i}’ :i的值為空

awk ‘BEGIN{print !i}’ :i的值取反為1

[root@centos7 ~]#awk ‘BEGIN{i=0;print !i}’ :i有值為0 取反為1
1

[root@centos7 ~]#awk ‘BEGIN{i=1;print !i}’ :i有值為1 取反為0
0

[root@centos7 ~]#awk ‘BEGIN{i=”abc”;print !i}’
0

[root@centos7 ~]#awk ‘BEGIN{i=””;print !i}’
1

在AWK中發現一旦沒有值或空值,取反都為1
在AWK中通常認為0位假,1位真

###########################################################################################################################################

條件表達式(三目表達式)
三目表達式就是三個組合在一起
selector?if-true-expression:if-false-expression
如果selector結果是真就執行if-true-expression,反之就執行if-false-expression
例:
awk -F: ‘{$3>=1000?usertype=”Common User”:usertype=”Sysadmin or SysUser”;printf “%-20s:%-s\n”,$1,usertype}’ /etc/passwd
usertype=”Common User” 定義變量
usertype=”Sysadmin or SysUser” 定義變量
如果$3>=1000就執行usertype=”Common User”
如果不是$3>=1000就執行usertype=”Sysadmin or SysUser”
printf 格式字符輸出
– 是左對齊
“%-20s代表左對齊,寬度是20個字符
:是分隔符
%-s 左對齊
\n 回車,printf默認不會換行
$1,usertype 顯示文件的第一列和變量usertype

##########################################################################################################################################33

正則表達式
awk -F: ‘/^r/{print $1}’ /etc/passwd
以r開頭的行顯示第一列,以-F :為分隔符

df -h |awk ‘/^\/dev\/sd/{print $1,$5}’
/^\/dev\/sd/ 顯示以/dev/sd開頭的行
{print $1,$5} 顯示第一列和第五列

cat /etc/fstab |awk ‘/^#/’
顯示文件以#號開頭的行

cat /etc/fstab |awk ‘!/^#/’
‘!/^#/’ 取反
顯示不以#開頭的行

cat /etc/httpd/conf/httpd.conf |awk ‘!/^ *#/’
‘!/^ *#/’顯示不以空格和#號開頭的行

awk -F: ‘/\/bin\/bash$/{print $1,$NF}’ /etc/passwd
/\/bin\/bash$/ 顯示以/bin/bash 結尾的行
$NF 代表最后一個字段

awk -F: ‘$NF == “/bin/bash”{print $1,$NF}’ /etc/passwd

awk -F: ‘/^root\>/,/^nobody\>/{print $1}’ /etc/passwd
顯示以:為分隔符,以root開頭到nobody開頭的行,只顯示第一列
-F: 為分隔符
/^root\>/ root開頭 單詞錨定
/^nobody\> nobody開頭 單詞錨定
{print $1} 第一列

awk -F: ‘(NR>=10&&NR<=20){print NR,$1}’ /etc/passwd
給文件的從第10行到第20行加行號
NR代表第幾行
(NR>=10&&NR<=20) 代表大于等于10行 小于等于20的行
{print NR,$1} NR代表10到20之間的數字 ,數字后面跟文件的第一列

awk -F: ‘BEGIN{print “USER USERID”}{print $1,$3}END{print “end file”}’ /etc/passwd
打印文件的第一列和第三列 ,在每列的開頭添加表同,在結尾添加end file
BEGIN{print “USER USERID”}打印表頭 USER和USERID
{print $1,$3} 顯示第一列和第三列
END{print “end file”} 在結尾添加end file

0或者空為假不顯示
不為空和有值1為真
seq 10 |awk ‘i=0’ i等于0 為假 不顯示
seq 10 |awk ‘i=1’ i等于1 為真 顯示信息
打印奇數行
[root@centos7 ~]#seq 10 |awk ‘i=!i’ i的值為0 取反為1 所以打印1
1 i的值變成了1 ,取反為0假 所以2不打印
3 i的值變成了0 ,取反為1真 所以打印3
5 i的值變成了1 ,取反為0假 所以4不打印
7 i的值變成了0 ,取反為1真 所以打印5
9 i的值變成了1 ,取反為0假 所以6不打印
i的值變成了0 ,取反為1真 所以打印7
i的值變成了1 ,取反為0假 所以8不打印
i的值變成了0 ,取反為1真 所以打印9
i的值變成了1 ,取反為0假 所以10不打印


[root@centos7 ~]#seq 10 |sed -n ‘1~2p’ 用sed打印奇數行
1
3
5
7
9

打印偶數行
[root@centos7 ~]#seq 10 |awk ‘!(i=!i)’
2
4
6
8
10


[root@centos7 ~]#seq 10 |awk -v i=1 ‘i=!i’ 直接給i賦值為1
2
4
6
8
10


[root@centos7 ~]#seq 10 |sed -n ‘2~2p’ 用sed打印偶數行
2
4
6
8
10

####################################################################################################################################################

awk在文件中是一行一行執行的
awk控制語句if-else
語法 :if(condition){statement;…}[else statement]
if(condition1){statement1}else if(condition2){statement2}else{statement3}
使用場景:對AWK取得的整行活某個字段做條件判斷

例: awk -F: ‘{if($3>=1000)print $1,$3}’ /etc/passwd
在/etc/passwd文件中如果第3列大于等于1000就打印第一列和第三列
-F: 以:為分隔符
$3 第三列
if 判斷語句
if($3>=1000) 如果第3列大于等于1000
print $1,$3 打印第1列和第3列

例:awk -F: ‘{if($NF==”/bin/bash”)print $1,$7}’ /etc/passwd
在/etc/passwd文件中如果以:為分隔符,如果在最后一列是/bin/bash,就打印第一列和第七列
-F: 以:為分隔符 也可以用 -v FS=: 代替 FS是AWK的內部變量
$NF== :NF 是一行字段的數量,$NF代表最后一個字段 NF是awk的內部變量
if是判斷語句
if($NF==”/bin/bash”) 如果最后一個字段是/bin/bash
print $1,$7 打印第例和第7列

例:awk ‘{if(NF>5)print $0}’ /etc/fstab
在/etc/fstab文件中如果一行的字段數大于5就打印一整行

例:awk -F: ‘{if($3>=1000){printf “Common user:%s\n”,$1}else{printf “root or Sysuer:%s\n”,$1}}’ /etc/passwd
在/etc/passwd文件中如果第三列大于等于1000就執行Common user: %s\n”,$1,如果不是大于等于1000就執行root or Sysuer: %s\n”,$1
$1 是第一列
-F:是以:號為分隔符
if 判斷語句
{if($3>=1000) 如果第三列大于等于1000
%s 顯示字符串
\n 回車,printf默認不會換行
{printf “Common user:%s\n”,$1} 打印Common user:和第一列
else 如果第三列不是大于等于1000就執行
{printf “root or Sysuer:%s\n”,$1} 打印root or Sysuer:和第一列

或 :awk -F: ‘{if($3>=1000)printf “Common use:%s\n”,$1;else printf “root or sysuwer:%s\n”,$1}’ /etc/passwd

例 :df -h |awk -F% ‘/^\/dev\/sd/{print $1}’ |awk ‘$NF>=10{print $1,$5}’
在df -h命令中,先以%為分隔符,切割/dev/sd開頭的行,切割第一列,在以空格為分隔符,打印第一列和第五列最后一個字段是大于等于10的行
-F% 以%為分隔符
/^\/dev\/sd/ 以/dev/sd開頭的行 ,awk支持正則表達式,在正則表達式里面/號要加\轉義
{print $1} 打印一%百分號為分隔符的第一列
awk ‘$NF>=10{print $1,$5}’
$NF>=10 最后一列小于等于10 NF是awk的內置變量,代表一行有多少字段,$NF代表最后一個字段
{print $1,$5} 打印第一列和第五列

例 :awk ‘BEGIN{test=100;if(test>90){print “very good”}else if(test>60){print “good”}else{print “no pass”}}’
定義一個值test=100 ,如果test大于90就打印very good ,如果text大于60就打印good,如果都不是就打印no pass
BEGIN 不用輸出文件
test=100 定義一個test值
if判斷語句
if(test>90) 如果大于90
{print “very good”} 打印 very good
else 如果不符合上一條判斷
if(test>60) 如果test大于60
{print “good”} 打印 goot
else 如果不符合上一條判斷
{print “no pass”} 打印no pass

####################################################################################################################################################

while 循環

語法:while(condition){statement;…}
條件“真”,進入循環;條件“假”,退出循環
使用場景:
對一行內的多個字段逐一類似處理時使用
對數組中的各元素逐一處理時使用

awk在文件中是以一行一行執行的
例 :awk ‘/^[[:space:]]*linux16/{i=1;while(i<=NF){print $i,length($i);i++}}’ /etc/grub2.cfg
在/etc/grub2.cfg 文件中以沒有空格或多個空格且包含Linux16開頭的行,i定義一個值為1 循環,如果i小于等于一行的字段數,就打印第一列和這一列的字符數,執行后i加1
[[:space:]] 代表空格
* 代表沒有或一個或多個
^ 在正則表達式中代表開頭
/^[[:space:]]*linux16/ 代表以沒有空格或多個空格且包含Linux16開頭的行
i定義一個值為1
while 代表循環
(i<=NF) i代表1 NF代表一行的字段的數量 i小于等于字段數
length 代表一個字段有多少字符
length($i) i的字段有多少字符
i++ 當第一次循環往i加一 ,i變成2 i=2 ….i=5 直到符合i小于字段數的判斷在停止循環 awk在文件中是以一行一行執行的
{print $i,length($i);i++}} 打印i的字段,和i字段的字符數,在i加1 直到符合i小于字段數的判斷在停止循環 awk在文件中是以一行一行執行的

例 :awk ‘/^[[:space:]]*linux16/{i=1;while(i<=NF) {if(length($i)>=10) {print $i,length($i)};i++}}’ /etc/grub2.cfg
在/etc/grub2.cfg文件中 以沒有空格或多個空格且包含Linux16開頭的行,i定義一個值為1 循環判斷i是否小于等于字段數 ,如果i的字段數大于等于10,就打印i的列,和i列的字符數,在循環
[[:space:]] 代表空格
* 代表沒有或一個或多個
^ 在正則表達式中代表開頭
/^[[:space:]]*linux16/ 代表以沒有空格或多個空格且包含Linux16開頭的行
i定義一個值為1
while 代表循環
(i<=NF) i代表1 NF代表一行的字段的數量 i小于等于字段數
length 代表一個字段有多少字符
length($i) i的字段有多少字符
if 判斷語句
{if(length($i)>=10) 如果i字段的字符數大于等于10
i++ 當第一次循環往i加一 ,i變成2 i=2 ….i=5 直到符合i小于字段數的判斷在停止循環 awk在文件中是以一行一行執行的
{print $i,length($i)};i++}} 打印i的字段,和i字段的字符數,在i加1 直到符合i小于字段數的判斷在停止循環 awk在文件中是以一行一行執行的

do-while循環
語法:do {statement;…}while(condition)
意義:無論真假,至少執行一次循環體

例 :awk ‘BEGIN{ total=0;i=0;do{ total+=i;i++;}while(i<=100);print total}’
計算1到100的相加的和
BEGIN只執行一次,不用輸出文件
total=0 total定義一個值為0
i=0 i定義一個值為0
do 先執行一次
total+=i 代表total=total+i
i++ 當一次循環完成i+1
while 循環
while(i<=100) 判斷i小于等于100
print total 打印total

***********************************************************************************************************************************************88

bash for循環 判斷1到100相加的和
#!/bin/bash
sum=0 #定義一個值
for ((i=0;i<=100;i++));do
let sum+=i
done
echo sum=$sum

**************************************************************************************************************************************************************

switch語句
語法:switch(expression) {case VALUE1 or /REGEXP/: statement1; case
VALUE2 or /REGEXP2/: statement2; …; default: statementn}

例:awk ‘BEGIN{sum=0;for(i=1;i<=100;i++){if(i%2==0)continue;sum+=i}print sum}’
計算1到100偶數的和
BEGIN,不用輸入文件
sum=0 定義一個值為0
for循環
i=1 i定義一個值為0
i++ 當第一次循環往i加一 ,i變成2 i=2 ….i=5 直到符合i小于字段數的判斷在停止循環 awk在文件中是以一行一行執行的
for(i=1;i<=100;i++) 判斷i是否小于100,不小于加1
i%2==0 i取模2等于0 代表偶數
continue 取消本次循環,繼續下一次循環
sum+=i 代表sum等于sum加i
print sum 打印sum的值

例 :awk ‘BEGIN{sum=0;for(i=1;i<=100;i++){if(i==66)break;sum+=i}print sum}’
BEGIN,不用輸入文件
sum=0 定義一個值為0
判斷i是否小于100,不小于加1
if(i==66) 判斷如果i等于66
break 取消全部循環
um+=i 代表sum等于sum加i
print sum 打印sum的值

next:
提前結束對本行處理而直接進入下一行處理(awk自身循環)

例 :awk -F: ‘{if($3%2!=0) next;print $1,$3}’ /etc/passwd
在/etc/passwd文件中判斷如果第3列是奇數就不執行這一行,打印的一列和第三列
-F: 以:冒號為分隔符
if 判斷
$3%2 第三列取模2
!=0 不等于0
{if($3%2!=0) 如果第2例取模不等于0,就是奇數
next 結束這一行的處理
print $1,$3 打印第一列和第三列

例 :awk -F: ‘{if($3>10 && $3<100)print $1,$3}’ /etc/passwd
在/etc/passwd文件中查找大于10并且小于100的行,并打印第一列和第三列

***********************************************************************************************************************************************

awk的數組,它認為就是關聯數組,自定義索引也叫下標
數組就是一個數組里面放多個值,數組分為普通數組和關聯數組

例 :awk ‘BEGIN{title[“ceo”]=”mage”;title[“coo”]=”zhangsir”;print title[“coo”]}’
定義數組title 在title的數組中下標ceo的值是mage,coo下標的值是zhangsir ,打印title 數組的coo下標的值
BEGIN,不用輸入文件
title 數組 名字自定義
[“ceo”] 下標,因為是關聯數組所以下標自定義
[“coo”] 自定義下標
print title[“coo”]} 打印title 數組的coo下標的值

例:[root@centos7 ~]#cat f1.txt
aaa
bbb
ccc
aaa
bbb
ccc
ddd
ddd
eee
vvv
eee

[root@centos7 ~]#awk ‘!arr[$0]++’ f1.txt 去掉重復的行
aaa
bbb
ccc
ddd
eee
vvv

awk在文件中是一行一行執行的
在awk在1為真,0為假
$0是代表整行
arr[$0] 第一行是arr[aaa] 因為沒有值代表空,就是假不打印
! 代表取反
!arr[$0]++ arr數組的值為空是0為假取反是1為真打印,當碰見重復的行的時候+1是2,2取反就是假不打印

***************************************************************************************************************************************************************

遍歷
若要遍歷數組中的每個元素,要使用for循環
?for(var in array) {for-body}
?注意:var會遍歷array的每個索引

例 :awk ‘BEGIN{weekdays[“mod”]=”monday”;weekdays[“tue”]=”tuseday”;for(i in weekdays){print weekdays[i]}}’
顯示所有下標的值
BEGIN 不用輸出文件
weekdays 數組
[“mod”] 自定義下標
“monday” 下標的值
for 循環
i 是變量
for(i in weekdays) 循環i不斷的查找下標的值
print weekdays[i]} 打印數組下標的值

例 :netstat -nat |awk ‘/^tcp/{test[$NF]++}END{for(i in test){print i,test[i]}}’
在netstat -nat命令中,查找tcp開頭的行,test數組的下標是每行的最后一個字段,如果每行的最后一個字段有相同的就加1,所有的行處理完成用END遍歷顯示,用for循環i對應的下標,打印最后一個字段和出現的次數
/^tcp/ 代表以tcp開頭,在正則表達式中^代表開頭
test 代表數組可以自定義,一個數組里面可以有多個值,在數組中一個下標對應一個值
$NF 代表一行的最后一個字段,NF代表一行的所有字段的數量
++ 出現相同的就追加
{test[$NF]++} 添加一個test的數組,下標是$NF一行的最后一個字段,如果最后一個字段相同就加一
END 所有的行處理完成,用總的遍歷顯示
for循環
i 是一個變量代表了test數組的下標,就是一行的最后一個字段
test[i] 打印數量
{print i,test[i]}} 打印 最后一個字段,和這個字段出現的次數

例 cat access_log_\(1\) | awk ‘/^[0-9]/{ip[$1]++}END{for(i in ip){print i,ip[i]}}’
計算在 cat access_log_\(1\) 文件中相同ip出現的次數
awk 默認移空格為分隔符
/^[0-9]/ 以0-9的數字開頭
ip 定義一個數組
$1 代表第一列
++ 代表如果相同就追加1
{ip[$1]++} ip數組的下標是文件中的第一列,在第一列中如果有相同的加1
END 代表所有的行處理完成,用總的變量顯示
for 循環
i是變量 代表數組ip的下標
{print i,ip[i]}} 打印下標也就是第一列, 和所出現次數

####################################################################################################################################################

將某個ip放到防火墻,讓他ping不通自己
iptables -A INPUT -s 原地址ip -j REGEXP
iptables -A INPUT -s 172.20.110.34 -j REJECT 拒絕ip訪問
iptables -vnL 查看防火墻

如果ip的連接數大于1000就把這個ip放入防火墻
for i in `cat access_log_\(1\) | awk ‘/^[0-9]/{ip[$1]++}END{for(i in ip){if (ip[i]>=1000) print i}}’`;do
iptables -A INPUT -s $i -j REJECT
done

如果ip的連接數大于10000就把這個ip放入防火墻
awk ‘/^[0-9]/{ip[$1]++}END{for(i in ip){if(ip[i]>=10000) print i}}’ access_log_\(1\) 取出大于連接數10000的ip
while read ip;do #read的意思是逐行處理
iptables -A INPUT -s $ip -j REJECT
done

iptables -vnL 查看防火墻

查看ip連接數量最大的前10個
awk ‘/^[0-9]/{ip[$1]++}END{for(i in ip){ print i,ip[i]}}’ access_log_\(1\) |sort -k2 -nr |head
head 默認切割前10個

計算在文件中出現的單詞數量
cat /etc/rc.sysinit |awk ‘{for(i=1;i<=NF;i++){work[$i]++}}END{for(j in work){print j,work[j]}}’
NF 代表一行的字段數
{for(i=1;i<=NF;i++) 給i賦值為1 ,如果1小于字段數就加1 ,i變成2,在判斷2是否小于一行的字段數,一直判斷到i等于一行的字段數,在判斷繼續下一行
{work[$i]++} work是函數 $i代表一行單詞的數量,如果一行中有重復的單詞就加1
END 所有的行處理完成,用總的遍歷顯示

[root@centos6 ~]#cat kaos.txt
name score sex
mage 100 m
zhangsir 99 m
bai 90 f
li 100 f

統計男神和女神的考試成績的平均成績
awk ‘{if($NF==”m”){sum_m+=$2;num_m++}else{sum_f+=$2;num_f++}}END{printf “male:%.2f\nfemale:%.2f\n”,sum_m/num_m,sum_f/num_f}’ kaos.txt

awk ‘{num[$NF]++;SUM[$NF]+=$2 }END{printf “male:%.2f\nfemale:%.2f\n”,sum[“m”]/num[“m”],sum[“f”]/num[“f”]}’ kaos.txt

***********************************************************************************************************************************************************************************8

awk函數
awk自帶的函數
rand():返回0和1之間一個隨機數 隨機數不能自己生成得借助srand
例: awk ‘BEGIN{srand();print rand()}’

length([s]):返回指定字符串的長度
sub(r,s,[t]):對t字符串進行搜索r表示的模式匹配的內容,并將第一個匹配的內容替換為s
例 [root@centos6 ~]#echo “2008:08:08 08:08:08″ | awk ‘sub(/:/,”-“,$1)’
2008-08:08 08:08:08 $1替換的是第一列的第一個
例:echo “2008:08:08 08:08:08″ | awk ‘sub(/:/,”-“,$2)’
2008:08:08 08-08:08 $2替換的第二列的第一個

gsub(r,s,[t]):對t字符串進行搜索r表示的模式匹配的內容,并全部替換為s所表示的內容
例:[root@centos6 ~]#echo “2008:08:08 08:08:08″ | awk ‘gsub(/:/,”-“,$1)’
2008-08-08 08:08:08 $1替換的是第一列的全部
例:echo “2008:08:08 08:08:08″ | awk ‘gsub(/:/,”-“,$2)’
2008:08:08 08-08-08 $2 替換的是第二的全部
例:echo “2008:08:08 08:08:08″ | awk ‘gsub(/:/,”-“,$0)’
2008-08-08 08-08-08 $0替換的是全部

split(s,array,[r]):以r為分隔符,切割字符串s,并將切割后的結果保存至array所表示的數組中,
第一個索引值為1,第二個索引值為2,…
例:netstat -tan | awk ‘/^tcp\>/{split($5,ip,”:”);count[ip[1]]++}END{for (i in count) {print i,count[i]}}’
計算ip地址重復出現的次數

本文來自投稿,不代表Linux運維部落立場,如若轉載,請注明出處:http://www.www58058.com/98963

(0)
周亞飛周亞飛
上一篇 2018-05-20 15:45
下一篇 2018-05-20 17:34

相關推薦

  • if,case,for 腳本練習

    shell腳本練習

    2018-05-06
  • 網絡管理基礎

    1.PDU: Protocol Data Unit,協議數據單元是指對等層次之間傳遞的數據單位 ?物理層的 PDU是數據位 bit ?數據鏈路層的 PDU是數據幀 frame ?網絡層的PDU是數據包 packet ?傳輸層的 PDU是數據段 segment ?其他更高層次的PDU是消息 message 2.TCP特性工作在傳輸層 ?面向連接協議 ?全雙工協…

    Linux筆記 2018-05-02
  • keepalived介紹及相關實驗

    Keepalived是基于vrrp協議的一款高可用軟件。它的作用是檢測服務器的狀態,如果有一臺web服務器宕機,或工作出現故障,Keepalived將檢測到,并將有故障的服務器從系統中剔除,同時使用其他服務器代替該服務器的工作

    2018-07-13
  • 文件管理類命令和bash特性之(命令狀態返回值和命令行展開)

    文件管理類命令 ls 用途:list 列出指定目錄下的內容; 語法:ls [OPTION]… [FILE]… 選項:-a : 顯示所有文件,包括隱藏文件;-A :顯示除 . 和 .. 之外的所有文件;-l :長格式列表,顯示文件的詳細屬性信息;-h :可以對文件大小進行單位換算是非精確值;-d:查看目錄自身而非其內部文件列表(如果文件符合也會顯示出來);-r…

    2018-05-19
  • 開篇–送給自己

    這段文章是勉勵自己的,各位看官請自行跳過

    Linux筆記 2018-06-25
欧美性久久久久