19-三剑客之awk补充

2019-04-22  本文已影响0人  文娟_狼剩

创建环境:

head /etc/passwd >/oldboy/passwd.txt 

mkdir -p /server/files/
cat >>/server/files/reg.txt<<EOF
Zhang Dandan    41117397   :250:100:175
Zhang Xiaoyu    390320151  :155:90:201
Meng  Feixue    80042789   :250:60:50
Wu    Waiwai    70271111   :250:80:75
Liu   Bingbing  41117483   :250:100:175
Wang  Xiaoai    3515064655 :50:95:135
Zi    Gege      1986787350 :250:168:200
Li    Youjiu    918391635  :175:75:300
Lao   Nanhai    918391635  :250:100:175
EOF

一、awk的参数:

-F 指定分隔符
-v 修改或创建awk内置变量

二、内置变量

NR:记录行行号
NF:当前记录数中的个数,就是多少列
$(NF-n):倒数第n列,n为数字
$数字:某一列
$0:一整行
FS:-F修改的内容(Filed Separator 菜单 分隔符)
OFS(Output Filed Separator输出分隔符)
    awk在显示每一列的时候,每一列之间通过什么分割
    OFS的内容就是逗号的内容   

三、过滤(awk中什么可以作为条件)

3.1 比较

如:#找出/etc/passwd第3列中大于999的行
    awk -F':' '$3>999' /etc/passwd
如:#找出/etc/passwd第4列中大于0并且小于1000的行
    awk -F':' '$4>0&&$4<1000' /etc/passwd

3.2 正则

在awk中正则表达式都只支持,大部分中含义不变, 只有^和$在awk中的含义有些不一样

正则表达式 含义 Awk中的含义
^ 以……开头的行,如:/^oldboy/ 某一列中以……开头,如:$3~/^oldboy/
$ 以……结尾的行,如:/oldboy$/ 某一列中以……结尾,如:$3~/oldboy$/

注:某一列有什么,用~(波浪线)

3.2.1 awk中正则应用

#显示Xiaoyu的姓氏和ID号码

[root@oldboyedu59 /oldboy]# #显示Xiaoyu的姓氏和ID号码
[root@oldboyedu59 /oldboy]# #条件:显示Xiaoyu
[root@oldboyedu59 /oldboy]# #{动作}: 显示姓氏和id 
[root@oldboyedu59 /oldboy]# awk '$2~/Xiaoyu/' /server/files/reg.txt
Zhang Xiaoyu    390320151  :155:90:201
[root@oldboyedu59 /oldboy]# 
[root@oldboyedu59 /oldboy]# awk '$2~/Xiaoyu/{print $1,$3}' /server/files/reg.txt
Zhang 390320151

#姓氏是Zhang的人,显示他的第二次捐款金额及她的名字

[root@oldboyedu ~]# awk -F '[ :]+' '$1~/^Zhang/{print $2,$5}' /server/files//reg.txt 
Dandan 100
Xiaoyu 90

取最后一列可以用$NF,倒数第二列$(NF-1),以此类推
[root@oldboyedu ~]# awk -F '[ :]+' '$1~/Zhang/{print $2,$(NF-1)}' /server/files//reg.txt 
Dandan 100
Xiaoyu 90

#显示所有ID号码最后一位数字是1或5的人的全名

[root@oldboyedu ~]# awk '$3~/[15]$/{print $1,$2}' /server/files//reg.txt
[root@oldboyedu ~]# awk '$3~/(1|5)$/{print $1,$2}' /server/files//reg.txt
Zhang Xiaoyu
Wu Waiwai
Wang Xiaoai
Li Youjiu
Lao Nanhai

#显示所有人的全名,以姓,名的格式显示,如Meng,Feixue

[root@oldboyedu ~]# awk '{print $1","$2}' /server/files//reg.txt 
Zhang,Dandan
Zhang,Xiaoyu
Meng,Feixue
Wu,Waiwai
Liu,Bingbing
Wang,Xiaoai
Zi,Gege
Li,Youjiu
Lao,Nanhai

#显示Xiaoyu的捐款.每个值时都有以$开头.如$520$200$135------可以用多种方法(比如:sed、tr)

[root@oldboyedu ~]# awk -F'[ :]+' '$2~/Xiaoyu/{print "$"$4"$"$5"$"$6}' /server/files//reg.txt
$155$90$201
[root@oldboyedu ~]# awk '$2~/Xiaoyu/{print $4}' /server/files//reg.txt|sed 's#:#$#g'
$155$90$201
[root@oldboyedu ~]# awk '$2~/Xiaoyu/{print $4}' /server/files//reg.txt|tr ':' '$'
$155$90$201

3.3 范围

sed -n '1,5p' oldboy.txt
awk 'NR==1,NR==5' oldboy.txt
sed -n '/11:10/,/12:10/p'   access.log
awk '/11:10/,/12:10/'   access.log
awk '$4~/11:10/,$4~/12:10/'   access.log

3.4 特殊

3.4.1 BEGIN{}

里面的内容会在awk读取文件之前运行
进行测试

#BEGIN{}的使用
[root@oldboyedu ~]# awk 'BEGIN{print 1/3,2*2*2*2,2^10}'
0.333333 16 1024

3.4.2 END{}

里面的内容会在awk读取文件之后运行
显示计算结果

END{}的使用
统计/etc/services这个文件中空行有多少个

[root@oldboyedu ~]# awk '/^$/{i++}END{print i}' /etc/services 
17

四、awk替换

格式:
gsub(/找谁/,"替换成什么")
gsub(/找谁/,"替换成什么",某一列)
注:这个命令是awk中的动作,估需要写在{}中,多个命令之间用;隔开

#显示Xiaoyu的捐款.每个值时都有以$开头.如$520$200$135------用awk下的gsub命令

[root@oldboyedu ~]# awk '{gsub(/:/,";"); print $4}' /server/files//reg.txt
;250;100;175
;155;90;201
指定替换某一列
[root@oldboyedu ~]# awk '{gsub(/:/,";",$NF); print $4}' /server/files//reg.txt
;250;100;175
;155;90;201

创建环境:

head /etc/passwd >/oldboy/passwd.txt 

#调换/oldboy/passwd.txt文件的第1列和最后一列的位置(不用修改文件内容)

OFS awk在显示每一列的时候 每一列之间通过什么分割
OFS的内容就是 ,的内容
Output Field Separator 输出分隔符

image.png

不加-vOFS的

[root@oldboyedu ~]# awk -F: '{tmp=$1;$1=$NF;$NF=tmp;print $0 }' /oldboy/passwd.txt
/bin/bash x 0 0 root /root root
/sbin/nologin x 1 1 bin /bin bin
/sbin/nologin x 2 2 daemon /sbin daemon
/sbin/nologin x 3 4 adm /var/adm adm
/sbin/nologin x 4 7 lp /var/spool/lpd lp
/bin/sync x 5 0 sync /sbin sync
/sbin/shutdown x 6 0 shutdown /sbin shutdown
/sbin/halt x 7 0 halt /sbin halt
/sbin/nologin x 8 12 mail /var/spool/mail mail
/sbin/nologin x 11 0 operator /root operator
[root@oldboyedu ~]# 

加-vOFS之后的结果

[root@oldboyedu59 /oldboy]# awk -F: -vOFS=":" '{tmp=$1;$1=$NF;$NF=tmp;print $0 }' /oldboy/passwd.txt
/bin/bash:x:0:0:root:/root:root
/sbin/nologin:x:1:1:bin:/bin:bin
/sbin/nologin:x:2:2:daemon:/sbin:daemon
/sbin/nologin:x:3:4:adm:/var/adm:adm
/sbin/nologin:x:4:7:lp:/var/spool/lpd:lp
/bin/sync:x:5:0:sync:/sbin:sync
/sbin/shutdown:x:6:0:shutdown:/sbin:shutdown
/sbin/halt:x:7:0:halt:/sbin:halt
/sbin/nologin:x:8:12:mail:/var/spool/mail:mail
/sbin/nologin:x:11:0:operator:/root:operator

五、awk计算

i=i+1
    进行基数,计算一共出现了多少次
i=i+$n
    $n取第n列的值,n为数字
    进行计算总和
    求和(累加)
统计access.log这个文件中第9列等于200的个数
[root@oldboyedu ~]# awk '$9~/200/{i++}END{print i}' access.log
142666
[root@oldboyedu ~]# awk '$9==200{i=i+1}END{print i}' access.log
142666
[root@oldboyedu ~]# 

统计1+……+100等于多少
[root@oldboyedu ~]# seq 100|awk '{i=i+$1}END{print i}'
5050
[root@oldboyedu ~]# 
上一篇下一篇

猜你喜欢

热点阅读