三剑客之三 Awk小记
AWK 编程语言
作用:
1)查询文本内的信息
2)判断 循环 数组等
3)统计数据 计算
awk '找谁{动作}' file #文件的标准输入
cat file|awk '找谁{动作}' #其他命令的标准输出
awk中的变量:
#在awk中所有的字符串和空格都是一个变量
#在awk中输出字符串和空格都需要加上"" 双引号
NR 行号
-F 分隔符 默认以空格和tab键作为分隔符
$0 把每行的内容赋值给0
$1 每行的第一列
$n 每行的第n列
, 默认为空格
NF 存储了每一行的最后一列 最后列的列号
1.NR 取行
1) awk取行 NR 行号
表示方法: awk 'NR==3' file
== 等于
> 大于
< 小于
>= 大于等于
<= 小于等于
!= 不等于
&& 并且
|| 或者
2)取出文件中的第三行 使用 NR==3
[root@oldboy~]#awk 'NR==3' test.txt
Meng Feixue 80042789 :250:60:50
3) 取出文件中大于3行的内容 使用NR>3
[root@oldboy~]#awk 'NR>3' test.txt
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
4) 取出文件中小于第三行的内容 NR<3
[root@oldboy~]#awk 'NR<3' test.txt
Zhang Dandan 41117397 :250:100:175
Zhang Xiaoyu 390320151 :155:90:201
5) 取出不等于1的行 NR!=1
[root@oldboy~]#awk 'NR!=1' test.txt
Zhang Xiaoyu 390320151 :155:90:201
Meng Feixue 80042789 :250:60:50
Wu Waiwai 70271111 :250:80:75
6)大于1并且小于5 NR>1 && NR<5
[root@oldboy~]#awk 'NR>1 && NR<5' test.txt
Zhang Xiaoyu 390320151 :155:90:201
Meng Feixue 80042789 :250:60:50
Wu Waiwai 70271111 :250:80:75
7) 等于3 或者等于5 NR==3 || NR==5
[root@oldboy~]#awk 'NR==3||NR==5' test.txt
Meng Feixue 80042789 :250:60:50
Liu Bingbing 41117483 :250:100:175
2.awk取列 #默认以空格和tab键作为分隔符
$0 代表了所有的行
$1 代表了第一列
$2 代表了第二列
$n 代表了第n列
#给取出的内容加上行号
[root@web01 ~]# awk '{print NR $0}' passwd
1root:x:0:0:root:/root:/bin/bash
2bin:x:1:1:bin:/bin:/sbin/nologin
3daemon:x:2:2:daemon:/sbin:/sbin/nologin
4adm:x:3:4:adm:/var/adm:/sbin/nologin
5lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6sync:x:5:0:sync:/sbin:/bin/sync
7shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8halt:x:7:0:halt:/sbin:/sbin/halt
9mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
10operator:x:11:0:operator:/root:/sbin/nologin
1)打印文本的第一列 awk '{print $n}' test.txt
[root@oldboy~]#awk '{print $1}' test.txt
Zhang
Zhang
Meng
Wu
2)同时取出第一列和第三列的内容 逗号, 变量 里面默认的是空格
[root@oldboy~]#awk '{print $1,$3}' test.txt
Zhang 41117397
Zhang 390320151
Meng 80042789
3)注意事项 awk中所有的普通字符串默认多视为变量 取消变量使用 "" (双引号)
[root@oldboy~]#awk '{print $1"aaaa"$3}' test.txt
Zhangaaaa41117397
Zhangaaaa390320151
Mengaaaa80042789
[root@oldboy~]#awk '{print $1" aaaa "$3}' test.txt
Zhang aaaa 41117397
Zhang aaaa 390320151
Meng aaaa 80042789
[root@oldboy~]#awk '{print $1"\t"$3}' test.txt
Zhang 41117397
Zhang 390320151
Meng 80042789
4)先输出文本的第3列 然后在输出第一列 以空格分隔
[root@oldboy~]#awk '{print $3,$1}' test.txt
41117397 Zhang
390320151 Zhang
80042789 Meng
70271111 Wu
41117483 Liu
[root@web01 ~]# awk -F: '{print$7,":"$2,":"$3,":"$4,":"$5,":"$6,":"$1}' passwd
/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
5) 输出最后一列
[root@oldboy~]#cat 3.txt
a b c d e
a b c d e f
[root@oldboy~]#awk '{print NF}' 3.txt
5
6
[root@oldboy~]#awk '{print $NF}' 3.txt
e
f
[root@web01 ~]# awk -F: '{print$(NF-1)}' passwd #取出倒数第二列
/root
/bin
/sbin
/var/adm
/var/spool/lpd
/sbin
6) 取出第三行的第二列
awk '模式 {动作}'
[root@oldboy~]#awk 'NR==3' test.txt
Meng Feixue 80042789 :250:60:50
[root@oldboy~]#awk 'NR==3{print $2}' test.txt
Feixue
7) 模糊匹配 awk不区分大小写
[root@oldboy~]#awk '/Bingbing/' test.txt
Liu Bingbing 41117483 :250:100:175
[root@oldboy~]#
[root@oldboy~]#awk '/Bingbing/{print}' test.txt
Liu Bingbing 41117483 :250:100:175
8) 匹配区间
[root@oldboy~]#awk '/Bingbing/,/Gege/' test.txt #词组之间用逗号隔开
Liu Bingbing 41117483 :250:100:175
Wang Xiaoai 3515064655 :50:95:135
Zi Gege 1986787350 :250:168:200
PS: , 的区别
sed '//,//' # 模式 匹配过滤内容
awk '//,//' # 模式 匹配顾虑内容
awk '//,//{print $1,$2}' # 逗号在匹配过滤中是区间 在动作中是空格
9) 使用-F 分隔来取列
PS:如果使用-F定义分隔符 则默认的空格和tab键失效
[root@oldboy~]#cat 1.txt
root:x:0:0:root:/root:/bin/bash
root alex lida root
[root@oldboy~]#awk '{print $1}' 1.txt #默认空格喂分隔符
root:x:0:0:root:/root:/bin/bash
root
写法1
[root@oldboy~]#cat 1.txt
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
[root@oldboy~]#awk -F ":" '{print $1}' 1.txt
root
bin
写法2
[root@oldboy~]#awk -F: '{print $1}' 1.txt
root
bin
例子: 使用/作为分隔符
[root@oldboy~]#cat 1.txt
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
[root@oldboy~]#awk -F/ '{print $2}' 1.txt
root:
bin:
[root@oldboy~]#awk -F/ '{print $3}' 1.txt
bin
sbin
例子: 使用字符串或者单词的方式分隔
[root@oldboy~]#cat 2.txt
alexheheoldboy
lidaohehetest
[root@oldboy~]#awk -Fhehe '{print $1}' 2.txt
alex
lidao
例子:多次分隔
[root@oldboy~]#awk -F/ '{print $1}' 1.txt
root:x:0:0:root:
bin:x:1:1:bin:
[root@oldboy~]#awk -F/ '{print $1}' 1.txt|awk -F: '{print $3}'
0
1
注意:-F 覆盖默认的空格和tab键
[root@oldboy~]#cat 2.txt
al exheheold boy
lid aohehe test
[root@oldboy~]#awk '{print $1}' 2.txt
al
lid
[root@oldboy~]#awk -Fhehe '{print $1}' 2.txt
al ex
lid ao
10. 使用多个符号作为分隔符
[root@oldboy~]#cat 1.txt
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
[root@oldboy~]#awk -F/ '{print $2}' 1.txt
root:
bin:
[root@oldboy~]#awk -F: '{print $6}' 1.txt
/root
/bin
[root@oldboy~]#cat 1.txt
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
[root@oldboy~]#awk -F "[:/]" '{print $7}' 1.txt
root
bin
11. 把连续出现的: 作为分隔符
[root@oldboy~]#awk -F "[:]+" '{print $1}' 1.txt
root
bin
[root@oldboy~]#awk -F "[:]+" '{print $2}' 1.txt
x
x
[root@oldboy~]#cat 1.txt
root::x:0:0:root:/root:/bin/bash
bin::x:1:1:bin:/bin:/sbin/nologin
[root@oldboy~]#awk -F "::::" '{print $2}' 4.txt
hehe
[root@oldboy~]#awk -F "[:]+" '{print $2}' 4.txt
hehe
例子: 可以同时指定多个不同的字符作为分隔符
[root@oldboy~]#cat 1.txt
root::x:0:0:root:/root:/bin/bash
bin::x:1:1:bin:/bin:/sbin/nologin
[root@oldboy~]#awk -F "[:/]+" '{print $5}' 1.txt
root
bin
NR 记录的是行号
[root@oldboy~]##awk '{print NR}' 1.txt
[root@oldboy~]#cat 1.txt
root::x:0:0:root:/root:/bin/bash
bin::x:1:1:bin:/bin:/sbin/nologin
[root@oldboy~]#awk '{print NR}' 1.txt
1
2
[root@oldboy~]#
[root@oldboy~]#awk '{print NR$0}' 1.txt
1root::x:0:0:root:/root:/bin/bash
2bin::x:1:1:bin:/bin:/sbin/nologin
[root@oldboy~]#
[root@oldboy~]#awk '{print NR,$0}' 1.txt
1 root::x:0:0:root:/root:/bin/bash
2 bin::x:1:1:bin:/bin:/sbin/nologin
根据文件的行数进行执行动作
[root@oldboy~]#cat 1.txt
root::x:0:0:root:/root:/bin/bash
bin::x:1:1:bin:/bin:/sbin/nologin
[root@oldboy~]#awk '{print ok}' 1.txt
[root@oldboy~]#
[root@oldboy~]#awk '{print "ok"}' 1.txt
ok
ok
12.BEGIN 在读取文件之前的动作
格式: awk 'BEGIN{动作}{对文件做什么动作}' file
[root@oldboy~]#awk '{print "ok"}' 1.txt
ok
ok
[root@oldboy~]#awk 'BEGIN{print "开始了"}'
开始了
[root@oldboy~]#
[root@oldboy~]#awk '{print "ok"}'
^C
[root@oldboy~]#awk 'BEGIN{print "开始了"}'
开始了
[root@oldboy~]#awk 'BEGIN{print "开始了"}{print "ok"}' 1.txt
开始了
ok
ok
13.END 在读取文件之后的动作 常用 awk统计、数组
格式: awk '{文件的动作}END{结束后的动作}' file
[root@oldboy~]#awk '{print "ok"}' 1.txt
ok
ok
[root@oldboy~]#
[root@oldboy~]#awk '{print "ok"}END{print "结束了"}' 1.txt
ok
ok
结束了
BEGIN和END结合
[root@oldboy~]#awk -F: 'BEGIN{print "开始"}{print $1}END{print "结束"}' 1.txt
开始
root
bin
结束
14.使用正则匹配字符串
过滤以root开头的行
[root@oldboy~]#cat 1.txt
root::x:0:0:root:/root:/bin/bash
bin::x:1:1:bin:/bin:/sbin/nologin
[root@oldboy~]#awk '/^root/' 1.txt
root::x:0:0:root:/root:/bin/bash
过滤以bash结尾的行
[root@oldboy~]#awk '/bash$/' 1.txt
root::x:0:0:root:/root:/bin/bash
[root@oldboy~]#awk '/nologin$/' 1.txt
bin::x:1:1:bin:/bin:/sbin/nologin
按照列来使用正则匹配内容
[root@oldboy~]#cat 1.txt
root::x:0:0:root:/root:/bin/bash
bin::x:1:1:bin:/bin:/sbin/nologin
[root@oldboy~]#awk -F: '{print $NF}' 1.txt
/bin/bash
/sbin/nologin
[root@oldboy~]#awk -F: '$NF ~ /in$/' 1.txt
bin::x:1:1:bin:/bin:/sbin/nologin
[root@oldboy~]#
[root@oldboy~]#
[root@oldboy~]#awk -F: '$NF ~ /in$/{print $1}' 1.txt
bin
[root@oldboy~]#awk -F: '$1 ~ /root/' 1.txt
root::x:0:0:root:/root:/bin/bash
[root@oldboy~]#
[root@oldboy~]#awk -F: '$1 ~ /^root/' 1.txt
root::x:0:0:root:/root:/bin/bash
[root@oldboy~]#
[root@oldboy~]#awk -F: '$0 ~ /^root/' 1.txt
root::x:0:0:root:/root:/bin/bash
[root@oldboy~]#cat 1.txt
root::x:0:0:root:/root:/bin/bash
bin::x:1:1:bin:/bin:/sbin/nologin
[root@oldboy~]##root ~ ^root # 按照第一列进行匹配
[root@oldboy~]#
[root@oldboy~]##root::x:0:0:root:/root:/bin/bash ~ ^root # 按整行进行匹配
awk匹配规则取反 了解
[root@oldboy~]#cat 1.txt
root::x:0:0:root:/root:/bin/bash
bin::x:1:1:bin:/bin:/sbin/nologin
[root@oldboy~]#awk -F: '$NF ~ /in$/' 1.txt
bin::x:1:1:bin:/bin:/sbin/nologin
[root@oldboy~]#awk -F: '$NF !~ /in$/' 1.txt
root::x:0:0:root:/root:/bin/bashr'f
1. 排除空行 存在空格和tab键的空行
[root@qls ~]# cat sshd_config
# $OpenBSD: sshd_config,v 1.100 2016/08/15 12:32:04 naddy Exp $
# This is the sshd server system-wide configuration file. See
# sshd_config(5) for more information.
# This sshd was compiled with PATH=/usr/local/bin:/usr/bin
# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented. Uncommented options override the
# default value.
# If you want to change the port on a SELinux system, you have to tell
# SELinux about this change.
# semanage port -a -t ssh_port_t -p tcp #PORTNUMBER
#
Port 22
#AddressFamily any
ListenAddress 0.0.0.0
#ListenAddress ::
[root@qls ~]# grep -v '^$' sshd_config
[root@qls ~]# sed '/^$/d' sshd_config
[root@qls ~]# awk '!/^$/' sshd_config
# -P 支持tab键
[root@qls ~]# grep -Pv '^[ \t]*$' sshd_config
[root@qls ~]# sed '/^[ \t]*$/d' sshd_config
[root@qls ~]# awk '!/^[ \t]*$/' sshd_config
# \s 空白字符
[root@qls ~]# grep -v '^\s*$' sshd_config
[root@qls ~]# sed '/^\s*$/d' sshd_config
[root@qls ~]# awk '!/^\s*$/' sshd_config
2. 排除空行和注释行 #号开头的
[root@qls ~]# grep -Ev '^$|^#' sshd_config
[root@qls ~]# grep -Ev '^\s*$|^#' sshd_config
Port 22
ListenAddress 0.0.0.0
[root@qls ~]# sed -r '/^\s*$|^#/d' sshd_config
Port 22
ListenAddress 0.0.0.0
[root@qls ~]# sed -r '/^[ \t]*$|^#/d' sshd_config
Port 22
ListenAddress 0.0.0.0
[root@qls ~]# awk '!/^[ \t]*$|^#/' sshd_config
Port 22
ListenAddress 0.0.0.0
[root@qls ~]# awk '!/^\s*$|^#/' sshd_config
Port 22
ListenAddress 0.0.0.0
3. 将/etc/passwd文件中的第一列和第七列位置进行调换 awk 等值替换
[root@qls ~]# awk -F '[:]' '{a=$1;$1=$NF;$NF=a;print}' passwd | tr ' ' ':'
/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
[root@qls ~]# awk -F '[:]' -vOFS=":" '{a=$1;$1=$NF;$NF=a;print}' passwd
/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