本文共 9968 字,大约阅读时间需要 33 分钟。
awk与sed的区别?
awk与sed一样,均是一行一行的读取数据,进行处理的,但不同点在于,sed用作一整行的整理,而awk是将一行分成多个字段来处理的AWK 是一种处理文本文件的语言,是一个强大的文本分析工具,功能十分强大。
之所以叫 AWK 是因为其取了三位创始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的 Family Name 的首字符。1. awk的数据字段变量
awk 默认的字段分隔符是任意空白字符(空格或TAB) $0表示整行文本 $1表示文本中第一个数据字段 $2表示文本中第二个数据字段 $n表示文本中第n个数据字段2.awk命令的完整语法
awk’BEGIN{commands}pattern{commands}END{commmands}’ 命令的执行过程: BEGIN 只在开始时执行 pattern 每行都要执行 END只在最后执行 3.awk命令的基本语法awk –F 分隔符 ‘/模式/{动作}’ 文件
awk 的指令一定要用单括号 awk 的动作一定要用花括号 模式可以是正则表达式,条件表达式或两种组合,如果模式是正则表达式要用 / 正则表达式/ 界定符 多个动作之间用;分开4.awk常用命令选项
-F fs
fs指定输入分隔符,fs可以是字符串或正则表达式,如-F: -v var=$value 赋值一个用户定义变量,将外部变量传递给awk -f scripfile 从脚本文件中读取awk命令 5.awk命令的操作符 正则表达式相关符号 数学运算符:+ - * / % ++ – 逻辑运算符:&&(与),||(或),!(非) 比较操作符:> >= < <= != == ~ !~ 文本数据表达式:==(精确匹配) ~表示匹配后面的模式,多用正则表达式6.awk 进行小数的比较和运算
[root@sc-changsha 7-8]# a=6.7[root@sc-changsha 7-8]# b=7.8#awk里使用双引号将shell变量传递到awk内部[root@sc-changsha 7-8]# echo |awk "{if ($a > $b) print 0 ; else print 1 }" 1[root@sc-changsha 7-8]# echo |awk "{print $a + $b}" 14.5[root@sc-changsha 7-8]# echo |awk "{print $a * $b}"52.26[root@localhost ~]# echo |awk "{print 12+12.3}"24.3[root@localhost ~]# echo 12.1+223.2|bc235.3
7.awk命令的内部变量
NF:每行的字段数 NR:当前处理的行号 FS:当前的输入分隔符,默认是空白 OFS:当前的输出分隔符,默认是空白8.awk命令引用shell变量
-v 引入shell变量[root@localhost ~]# name=haha[root@localhost ~]# echo |awk -v var=$name '{print var}'haha
用双引号“ ”
不使用-v选项,直接使用shell里的变量,使用双引号,花括号里的$符号需要转义[root@localhost ~]# name=haha[root@localhost ~]# echo|awk '{print "'$name'"}'haha[root@localhost lianxi]# cat /etc/passwd|awk -F: "/$name/ {print \$1,\$2,\$3}"zwx x 688zwx1 x 1013zwx2 x 1014zwx3 x 1015zwx4 x 1016zwx5 x 1017zwx6 x 1018zwx7 x 1019zwx8 x 1020zwx9 x 1021zwx10 x 1022zwxzzz x 7745zwxzz1 x 7746zwxztt x 7787[root@localhost lianxi]# cat /etc/passwd|awk -F: "/$name\>/ {print \$1,\$2,\$3}"zwx x 688
9.awk内置函数
length()计算字段长度 可以利用length()检查有无空口令用户[root@localhost ~]# cat /etc/passwd|awk -F: 'length($1)==3 {print $0}'bin:x:1:1:bin:/bin:/sbin/nologinadm:x:3:4:adm:/var/adm:/sbin/nologinftp:x:14:50:FTP User:/var/ftp:/sbin/nologintss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologinzwx:x:688:7910::/lianxi:/aszzx:x:1002:1002::/home/zzx:/bin/bashass:x:1006:1006::/home/ass:/bin/bash
10.awk基本命令示例
#只有模式没有动作,只有过滤作用,显示整行
[root@localhost /]# awk '/bash/' /etc/passwd
#显示第二个字段
[root@localhost /]# who|awk '{print $2}'tty1pts/2pts/4
#注:who 命令简介:显示目前登入系统的用户信息。如果用户是从一个远程机器登录的,那么该机器的主机名也会被显示出来。
[root@localhost /]# whoroot tty1 2020-07-31 19:28root pts/2 2020-08-19 05:48 (192.168.0.25)root pts/4 2020-08-19 07:07 (192.168.0.25)
#显示文件中以h开头的行中,以:为分隔符的第1个字段和第7个字段
[root@localhost /]# awk -F: '/^h/ {print $1,$7}' /etc/passwdhalt /sbin/halthaha /bin/bash
#输出不以h开头的行中,以:为分隔符的第1个字段和第7个字段
[root@localhost /]# awk -F: '/^[^h]/ {print $1,$7}' /etc/passwd
#还可以指定多个分隔符
#未指定分隔符前[root@localhost /]# awk '/^h/' /etc/passwdhalt:x:7:0:halt:/sbin:/sbin/halthaha:x:7767:7767::/home/haha:/bin/bash#指定:/为分隔符号[root@localhost /]# awk -F '[:/]' '/^h/ {print $1,$10}' /etc/passwdhalt halthaha bin
如果每行中的第三个字段的长度等于3,则输出该行的第1,3个字段
[root@localhost /]# cat /etc/passwd|awk -F: '$3~/\<...\>/ {print $1,$3}'systemd-coredump 999systemd-resolve 193polkitd 998unbound 997sssd 996rngd 995zwx 688nginx 994sanle 520saslauth 454pcp 453
[root@localhost /]# whoroot tty1 2020-07-31 19:28root pts/2 2020-08-19 05:48 (192.168.0.25)root pts/4 2020-08-19 07:07 (192.168.0.25)[root@localhost /]# who |awk '{print length($2)}'455[root@localhost /]# who |awk '$2~/\<...\>/{print}'root pts/2 2020-08-19 05:48 (192.168.0.25)root pts/4 2020-08-19 07:07 (192.168.0.25)
问题:为什么会输出第一行和第三行? 因为单词界定符< > 将/识别成了分隔符,认为pts是一个单词,2或4是一个单词
[root@localhost ~]# who |awk '$2~/\<...\>/ {print}'root pts/0 2020-08-21 08:05 (192.168.0.17)root pts/1 2020-08-20 21:03 (192.168.0.15)[root@localhost ~]# who |awk '$2~/\<.\>/ {print}'root pts/0 2020-08-21 08:05 (192.168.0.17)root pts/1 2020-08-20 21:03 (192.168.0.15)
一个seq产生的1-50的数据序列,如果该数对5取余=0或者该数以1开头,则输出该数
[root@localhost /]# seq 50 |awk '$1%5==0 || $1~/^1/{print $1}'151011121314151617181920253035404550
显示UID不等于GID的用户名
[root@localhost ~]# cat /etc/passwd|awk -F: '$3!=$4 {print $1}'
统计使用bash的用户数,并显示这些行
[root@localhost ~]# cat /etc/passwd|awk -F: 'BEGIN{i=0} /bash/ {i++;print $0}END{print "total:"i}'
11AWK内部变量的使用
显示每行及该行的字段数
[root@localhost ~]# cat /etc/passwd|awk -F: '{print $0,NF}'root:x:0:0:root:/root:/bin/bash 7bin:x:1:1:bin:/bin:/sbin/nologin 7daemon:x:2:2:daemon:/sbin:/sbin/nologin 7adm:x:3:4:adm:/var/adm:/sbin/nologin 7lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin 7sync:x:5:0:sync:/sbin:/bin/sync 7shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown 7halt:x:7:0:halt:/sbin:/sbin/halt 7mail:x:8:12:mail:/var/spool/mail:/sbin/nologin 7operator:x:11:0:operator:/root:/sbin/nologin 7
显示每行的第一个字段和最后一个字段
[root@localhost ~]# cat /etc/passwd|awk -F: '{print $1,$NF}'root /bin/bashbin /sbin/nologindaemon /sbin/nologinadm /sbin/nologinlp /sbin/nologinsync /bin/syncshutdown /sbin/shutdownhalt /sbin/haltmail /sbin/nologin
显示行号及每行的内容
[root@localhost ~]# cat /etc/passwd|awk -F: '{print NR,$0}'1 root:x:0:0:root:/root:/bin/bash2 bin:x:1:1:bin:/bin:/sbin/nologin3 daemon:x:2:2:daemon:/sbin:/sbin/nologin4 adm:x:3:4:adm:/var/adm:/sbin/nologin5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin6 sync:x:5:0:sync:/sbin:/bin/sync7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown8 halt:x:7:0:halt:/sbin:/sbin/halt
显示文件的第3到第5行
[root@localhost ~]# cat /etc/passwd|awk -F: 'NR==3,NR==5 {print NR,$0}'3 daemon:x:2:2:daemon:/sbin:/sbin/nologin4 adm:x:3:4:adm:/var/adm:/sbin/nologin5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
显示文件的第3和第5行
[root@localhost ~]# cat /etc/passwd|awk -F: 'NR==3 || NR==5 {print NR,$0}'3 daemon:x:2:2:daemon:/sbin:/sbin/nologin5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
1,根据文件批量创建用户,批量删除用户
[root@localhost lianxi]# cat 1.txthello 1231slann 1234gghdf 1235[root@localhost lianxi]# awk '{system("useradd "$1)}' 1.txt[root@localhost lianxi]# ls /home1.txt date1.txt dfgs gghdf haha helly slann vmlinuz-0-rescue-f6e57ea094fa4d989de0d0b5f1824c5a vmlinuz-4.18.0-193.el8.x86_64 xixi[root@localhost lianxi]# awk '{system("userdel -r "$1)}' 1.txt[root@localhost lianxi]# ls /home1.txt date1.txt dfgs haha vmlinuz-0-rescue-f6e57ea094fa4d989de0d0b5f1824c5a vmlinuz-4.18.0-193.el8.x86_64 xixi
2,if语句的使用
[root@localhost lianxi]# cat /etc/passwd|awk -F: '{if ($1~/\<...\>/) print $0}'bin:x:1:1:bin:/bin:/sbin/nologinadm:x:3:4:adm:/var/adm:/sbin/nologinftp:x:14:50:FTP User:/var/ftp:/sbin/nologintss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologinzwx:x:688:7910::/lianxi:/aszzx:x:1002:1002::/home/zzx:/bin/bashass:x:1006:1006::/home/ass:/bin/bashzaa:x:1007:1007::/home/zaa:/bin/bashaws:x:1008:1008::/home/aws:/bin/bash
升级版
[root@localhost lianxi]# cat /etc/passwd|awk -F: '{if ($1=="root") print "管理员是:"$1;else if ($1=="ftp") print "ftp用户是:"$1;else print "普通用户是:"$1}'管理员是:root普通用户是:bin普通用户是:daemon普通用户是:adm普通用户是:lp普通用户是:sync普通用户是:shutdown普通用户是:halt普通用户是:mail普通用户是:operator普通用户是:gamesftp用户是:ftp
进阶版
[root@localhost lianxi]# awk -F: 'BEGIN{i=0;j=0;k=0;a=""}{if($3==0){i++;a=a" "$1 } else if($3>1 && $3<1000){j++;b=b" "$1;} else {k++;c=c" "$1;}}END{print "管理员:",a," 数量:",i,"\n程序用户:",b,"数量:",j,"\n普通用户:",c,"数量:",k,"\n总共:",i+j+k}' /etc/passwd管理员: root 数量: 1 程序用户: daemon adm lp sync shutdown halt mail operator games ftp dbus systemd-coredump systemd-resolve tss polkitd unbound sssd sshd rngd zwx nginx sanle mysql saslauth mailnull smmsp tcpdump named pcp squid 数量: 30 普通用户: bin nobody zzx yilin aa as ass zaa aws zssd assds califeng cali123 zwx1 zwx2 zwx3 zwx4 zwx5 zwx6 zwx7 zwx8 zwx9 zwx10 gen chenran zhaiwenxiu sd aq zzz sdf wenlongwang zwxzzz zwxzz1 zwb user01 user02 user03 user04 user05 user06 user07 user08 user09 user10 user11 user12 user13 user15 user16 user17 user18 user19 user20 haha xixi sx1 sx2 sx3 zz1 zzz1 aaa bbb www qqq username aaaa ssss zww zwwa dfgs asas asdfa qqqqq zwxztt zwwxx iii asshjdh 数量: 77 总共: 108
或者
[root@localhost lianxi]# awk -F: 'BEGIN{super=0;admin=0;user=0;super2="";user2=""}{if($3==0){super=super+1;A[super]=$1}else if($3>=1&&$3<=999){admin=admin+1;B[admin]=$1}else{user=user+1;C[user]=$1}}END{for(k in A){print "管理员是",A[k],",数量是",super};for (k in B){super2=super2" "B[k]};print "程序用户是",super2,".数量是",admin;for (k in C){user2 = user2" "C[k]};print "普通用户是",user2,",数量是",user;print "总共有",admin+super+user,"个用户"}' /etc/passwd管理员是 root ,数量是 1程序用户是 bin daemon adm lp sync shutdown halt mail operator games ftp dbus systemd-coredump systemd-resolve tss polkitd unbound sssd sshd rngd zwx nginx sanle mysql saslauth mailnull smmsp tcpdump named pcp squid .数量是 31普通用户是 nobody zzx yilin aa as ass zaa aws zssd assds califeng cali123 zwx1 zwx2 zwx3 zwx4 zwx5 zwx6 zwx7 zwx8 zwx9 zwx10 gen chenran zhaiwenxiu sd aq zzz sdf wenlongwang zwxzzz zwxzz1 zwb user01 user02 user03 user04 user05 user06 user07 user08 user09 user10 user11 user12 user13 user15 user16 user17 user18 user19 user20 haha xixi sx1 sx2 sx3 zz1 zzz1 aaa bbb www qqq username aaaa ssss zww zwwa dfgs asas asdfa qqqqq zwxztt zwwxx iii asshjdh ,数量是 76总共有 108 个用户
自己编写脚本统计每秒钟ens33网卡的接受和发送数据的流量
[root@localhost lianxi]# watch -n 1 -d "ifconfig ens33|awk 'NR==5||NR==7{print $5}'"
使用awk计算seq 20产生的序列的和
[root@localhost lianxi]# seq 20|awk 'BEGIN{sum=0}{sum+=$1}END{print sum}'210
如何知道密码为空的用户有哪些?
[root@localhost ~]# cat /etc/shadow|awk -F: '$2~/*|!!/ {print $1}'bindaemonadmlpsyncshutdownhaltmailoperatorgamesftp
awk执行结果可以通过print的功能将字段数据打印显示。在使用awk命令中,常用逻辑操作符“&&”和“||”;
awk也可以进行简单的数学运算,如+ 、-、*、/、%、^分别表示加、减、乘、除、取余、乘方,还可以进行小数的运算。
awk还可以进行正则匹配
awk从输入文件或者标准输入中读入信息,与sed一样,信息的读入也是逐行读取的。不同的是,awk命令将文本文件中的一行视为一个记录,而将一行中的某一部分(列)作为记录的一个字段。
为了操作这些不同的字段(列),awk借用shell中类似于位置变量的方法,用$1、$2…$9顺序的表示不同列,$0表示整行。
不同字段与不同字段可以通过指定的方式进行分隔,awk默认的分隔符是空白(空格和TAB)。awk命令允许使用“-F分隔符”的形式来指定分隔符。
命令较多时,可以使用“BEGIN……END” 其中还可以加入if else语句。
转载地址:http://nmlzi.baihongyu.com/