博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
AWK超详解
阅读量:3959 次
发布时间:2019-05-24

本文共 9968 字,大约阅读时间需要 33 分钟。

文章目录


问题引入

awk与sed的区别?

awk与sed一样,均是一行一行的读取数据,进行处理的,但不同点在于,sed用作一整行的整理,而awk是将一行分成多个字段来处理的

一、AWK简介

AWK 是一种处理文本文件的语言,是一个强大的文本分析工具,功能十分强大。

之所以叫 AWK 是因为其取了三位创始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的 Family Name 的首字符。

二、使用步骤

1.awk命令使用须知

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

2.AWK进阶部分

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/

你可能感兴趣的文章
date 使用
查看>>
ipcalc
查看>>
网络 linux 禁止 ping
查看>>
ELF 格式详解
查看>>
chromium 使用
查看>>
linux 检测虚拟机类型
查看>>
go - 运行时:内存不足
查看>>
top 使用
查看>>
Linux Netlink通信机制详解
查看>>
rsync 远程同步
查看>>
nano使用
查看>>
c函数
查看>>
linux 链接
查看>>
centos6.x 添加开机启动服务
查看>>
zfs 简单使用
查看>>
linux EXT4格式分区扩容
查看>>
实现 du 命令
查看>>
git revert reset 使用
查看>>
一些比较好的golang安全项目
查看>>
HTTP状态码
查看>>