三剑客之三 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
 
 

posted @ 2021-08-16 18:13  芒果~~  阅读(115)  评论(0编辑  收藏  举报