AWK
什么是awk awk是一个编程语言 主要作用: 对文本和数据的处理 awk处理数据的流程 1.扫描文件内容,从上到下进行扫描,按照行进行处理 2.寻找匹配到的内容,进行读取到特定的模式中,进行行处理 3.行满足指定模式动作,则输出到屏幕上面,不满足丢弃 4.接着读取下一行继续处理,接着循环,直到文件的结尾 awk语法格式 awk [选项] command files 三种格式 行处理前 行处理中 行处理后 BEGIN 执行的命令 最后的显示 END #行处理前 [root@shell01 ~]# awk 'BEGIN{print 1 + 1}' 2 #行处理前+行处理中 (-F是简写) [root@shell01 ~]# awk -F: '{print $1}' /etc/passwd root bin #-F为处理前,等于BEGIN{FS=':'} {print $1}为行处理中 [root@shell01 ~]# awk 'BEGIN{FS=":"}{print $1}' /etc/passwd #输出分隔符默认为空格,这里修改为# [root@shell01 ~]# awk 'BEGIN{FS=":";OFS="#"}{print $1,$2}' /etc/passwd root#x bin#x daemon#x #行处理前+行处理中+行处理后 (END为行处理后,会在最后执行) [root@shell01 ~]# awk 'BEGIN{FS=":";OFS="#"}{print $1,$2}END{print "内容打印结束"}' /etc/passwd root#x bin#x ... 内容打印结束 #行处理前+行处理中+行处理后 (文件有几行,就打印几行OK) [root@shell01 ~]# awk 'BEGIN{print 1+1}{print "OK"}END{print "内容打印结束"}' /etc/hosts 2 OK OK 内容打印结束 [root@shell01 ~]# cat test.txt 10 10 10 [root@shell01 ~]# awk '{print $1+$2}' test.txt 20 [root@shell01 ~]# awk -F: '{print $1,$3}' /etc/passwd root 0 bin 1 awk的工作原理 1.awk将文件中的每一行作为输入,将每一行的数据赋值给内部变量 $0 2.awk开始进行字段分解,根据指定的分隔符,将每个字段进行赋值给内部变量 $1 $2 $3 3.awk默认的分隔为空白字符,由内部变量FS来确定,也可以使用-F进行指定对应的分隔符 4.awk处理时使用print进行打印已分隔后的字段 5.awk打印输出结果之后,不同字段之间由空格进行分隔,这个空格是由不同字段之间的逗号进行映射的,由内部变量OFS进行修改,OFS默认的输出分隔符就是空格 6.awk输出一行内容后,重新读取下一行内容,会覆盖内部变量$0,然后新的字符进行字段分割并进行处理。 #awk的命令格式 匹配 模式 动作 #匹配 模式(root就是模式) [root@shell01 shell13]# awk '/root/' passwd root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin #动作 [root@shell01 shell13]# awk '{print $1}' passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin #模式+动作 [root@shell01 shell13]# awk -F: '/root/{print $1}' passwd root operator #当根分区使用率大于多少则打印Available [root@shell01 shell13]# df Filesystem 1K-blocks Used Available Use% Mounted on /dev/sda3 18863104 1875848 16987256 10% / devtmpfs 487048 0 487048 0% /dev [root@shell01 ~]# df |awk '/\/$/{print $4}' 16987256 [root@shell01 ~]# df |awk '/\/$/{ if ($3>180000) print $4}' 16987256
Awk的内部变量
1. 输入分隔符 FS 输入分隔符 默认以空白字符为分隔符 [root@shell01 ~]# awk -F: '{print $1}' passwd [root@shell01 ~]# awk 'BEGIN{FS=":"}{print $1}' passwd #指定多个分隔符, :和空格 [root@shell01 ~]# awk -F '[ :]' '{print $3}' passwd #获取ip地址 [root@shell01 shell13]# ip a s eth0 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:0c:29:49:ee:cc brd ff:ff:ff:ff:ff:ff inet 10.0.0.2/24 brd 10.0.0.255 scope global noprefixroute eth0 #注意:行开头空格前面也算一个字符;如果碰到' /'空格和斜杠一起,算一个分割符 [root@shell01 ~]# ip a s eth0|awk -F '[ /]*' 'NR==3{print $3}' 2. 输出分隔符 OFS 默认输出分隔为空格, 打印的时候用逗号作为分割,逗号就是输出分隔符,在显示的时候,默认映射为空格。 [root@shell01 shell13]# awk -F: '{print $1,$2}' passwd root x bin x [root@shell01 shell13]# awk -F: '{print $1$2}' passwd rootx binx #-v指定内部变量,分隔符为@ [root@shell01 shell13]# awk -F: -vOFS="@" '{print $1,$2}' passwd root@x bin@x [root@shell01 shell13]# awk -F: 'BEGIN{OFS="$"}{print $1,$2}' passwd root@x bin@x 3. 内部变量NF 最后一列 # NF 表示每一行最后一列(列数) $NF 打印最后一列的内容 [root@shell01 shell13]# awk -F: '{print $NF}' passwd /bin/bash /sbin/nologin /sbin/nologin [root@shell01 shell13]# awk -F: '{print NF}' passwd 7 7 4. 内部变量$0 $0 表示整行内容 #没有过滤,打印所有内容 [root@shell01 shell13]# awk '{print $0}' passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin #取第一行 [root@shell01 shell13]# awk 'NR==1{print $0}' passwd root:x:0:0:root:/root:/bin/bas 5. 内部变量NR NR 表示是行号 $NR不可用 #NR显示行号 [root@shell01 shell13]# awk '{print NR,$0}' passwd 1 root:x:0:0:root:/root:/bin/bash 2 bin:x:1:1:bin:/bin:/sbin/nologin 3 daemon:x:2:2:daemon:/sbin:/sbin/nologin #第一行 [root@shell01 shell13]# awk 'NR==1' passwd root:x:0:0:root:/root:/bin/bash [root@shell01 shell13]# awk 'NR==1{print $0}' passwd root:x:0:0:root:/root:/bin/bash 6. 内部变量 FNR #FNR 显示行号,针对多个文件时进行处理 不同的文件显示各自的行号 #下面两个文件行号叠加了,没有区分 [root@shell01 shell13]# awk '{print NR,$0}' passwd test.txt 1 root:x:0:0:root:/root:/bin/bas ... 10 2: eth0: <BROADCASE,MU... #下面两个文件行号各区计算 [root@shell01 shell13]# awk '{print FNR,$0}' passwd test.txt 1 root:x:0:0:root:/root:/bin/bas ... 1 2: eth0: <BROADCASE,MU... #了解 #7. RS 输入记录分隔符 ORS 输出记录分隔符 8. awk格式化输出 [root@shell01 ~]# date |awk '{print "今年是: "$NF"年","今月为: "$2"月"}' 今年是: 2024年 今月为: Jun月 [root@shell01 ~]# awk -F: '{print "用户为: "$1,"UID为:"$3,"GID为: "$4}' /etc/passwd 用户为: root UID为:0 GID为: 0 用户为: bin UID为:1 GID为: 1 用户为: daemon UID为:2 GID为: 2 printf 函数输出(了解) %表示内容 -表示左对齐 20表示占20个字符 s表示字符类型 [root@shell01 ~]# awk -F: '{printf "%-20s %-10s %-10s\n", "用户为: "$1,"UID为:"$3,"GID为: "$4}' /etc/passwd 用户为: root UID为:0 GID为: 0 用户为: bin UID为:1 GID为: 1 用户为: daemon UID为:2 GID为: 2
Awk模式动作
1. 正则表达式 #获取root开头的 [root@shell01 ~]# awk '/^root/' /etc/passwd #获取每一行等于root开头的,和上面效果相同,~表示等于 [root@shell01 ~]# awk '$0 ~/^root/' /etc/passwd #获取第4列以root开头的 [root@shell01 ~]# awk -F: '$4 ~/^root/' /etc/passwd #取反,不以root开头 [root@shell01 ~]# awk '!/^root/' /etc/passwd [root@shell01 ~]# awk '$0 !~/^root/' /etc/passwd #不取第4列以root开头的 [root@shell01 ~]# awk -F: '$4 !~/^root/' /etc/passwd 2. 比较表达式 关系运算符 < 小于 <= 小于等于 == 等于 > 大于 >= 大于等于 != 不等于 [root@shell01 shell13]# awk -F: '$3==0' passwd root:x:0:0:root:/root:/bin/bash #下面{print $0}可以省略,默认打印该行 [root@shell01 shell13]# awk -F: '$5<0{print $0}' passwd #字符串比较 (字符串最好用引号引起来) [root@shell01 shell13]# awk -F: '$1=="root"' passwd root:x:0:0:root:/root:/bin/bash #不等于 [root@shell01 shell13]# awk -F: '$4 != "root"' passwd [root@shell01 ~]# df Filesystem 1K-blocks Used Available Use% Mounted on /dev/sda3 18863104 1875848 16987256 10% / devtmpfs 487048 0 487048 0% /dev [root@shell01 ~]# df |awk '/\/$/'|awk '$3 > 1800000{print $4}' 16987148 3. 条件表达式 #如果第3列大于2万就打印整行 [root@shell01 ~]# awk -F: '{if($3>20000)print $0}' /etc/passwd #每一行第3列大于1000打印最后一列,否则打印第一列 [root@shell01 ~]# awk -F: '{if($3>1000){print $NF} else {print $1}}' /etc/passwd 4. 运算表达式 [root@shell01 ~]# awk -F: '$3 * 100 > 50000' /etc/passwd polkitd:x:999:998:User for polkitd:/:/sbin/nologin nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin #如果$3乘以10大于1000打印最后一列,否则打印第一列 [root@shell01 ~]# awk -F: '{if($3*10>1000){print $NF} else {print $1}}' /etc/passwd root bin [root@shell01 shell13]# awk -F: '/sync/{print $3}' passwd 5 [root@shell01 shell13]# awk -F: '/sync/{print $3 + 10}' passwd 15 [root@shell01 shell13]# awk -F: '/sync/{print $3*2}' passwd 10 [root@shell01 shell13]# awk -F: '/sync/{print $3/5}' passwd 1 [root@shell01 shell13]# awk -F: '/sync/{print $3^5}' passwd 3125 [root@shell01 shell13]# awk -F: '/sync/{print $3%5}' passwd 0 [root@shell01 shell13]# awk -F: '/sync/{print $3,$4}' passwd 5 0 [root@shell01 shell13]# awk -F: '/sync/{print $3+$4}' passwd 5 5. 逻辑操作符 && 并且 || 或者 ! 非 #行数大于2并且行数小于4 [root@shell01 shell13]# awk 'NR>2 && NR<4' passwd daemon:x:2:2:daemon:/sbin:/sbin/nologin [root@shell01 shell13]# awk 'NR>2 || NR<4' passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin #不为1的行 [root@shell01 shell13]# awk 'NR!=1' passwd bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin #第1列为root且第三列大于10 [root@shell01 shell13]# awk -F: '$1 ~/root/ && $3 > 10' passwd #不以root开头 [root@shell01 shell13]# awk '!/^root/' passwd
Awk判断语句
if #1.打印系统管理员用户的数量 [root@shell01 ~]# awk -F: '$3==0' /etc/passwd |wc -l #通过判断第三列是否为零,i进行累计,最后输出i [root@shell01 ~]# awk -F: '{if($3==0){i++}}END{print "当前系统管理员用户的数量:"i}' /etc/passwd 当前系统管理员用户的数量:1 if else #打印系统管理员的数量和其他用户的数量 [root@shell01 ~]# awk -F: '{if($3==0){i++}else{j++}}END{print "当前系统管理员用户数量:"i,"当前系统其他用户数量:"j}' /etc/passwd 当前系统管理员用户数量:1 当前系统其他用户数量:23 #这里END中写两条print命令,用;隔开 [root@shell01 ~]# awk -F: '{if($3==0){i++}else{j++}}END{print "当前系统管理员用户数量:"i;print "当前系统其他用户数量:"j}' /etc/passwd 当前系统管理员用户数量:1 当前系统其他用户数量:23 if else if else #打印系统管理员的数量和系统用户的数量及普通用户的数量 (小于1000系统用户,大于1000普通用户) [root@shell01 ~]# awk -F: '{if($3==0){a++}else{if($3>0 && $3<1000){b++}else{c++}}}END{print "管理员数量:"a,"系统用户数量:"b,"普通用户数量:"c}' /etc/passwd 管理员数量:1 系统用户数量:22 普通用户数量:1
Awk循环语句
while循环 [root@shell01 shell13]# awk 'BEGIN{ i=1; while(i<=3){print i; i++}}' 1 2 3 #相当于每一行,都要循环到总列数,并打印1-列数 [root@shell01 ~]# awk -F: '{i=1; while(i<=NF){print i;i++}}' /etc/passwd #每一行都打印10次 [root@shell01 ~]# awk -F: '{i=1; while(i<=10){print $0;i++}}' /etc/passwd for循环 #把每行所有内容一个个打印出来 [root@shell01 shell13]# awk -F: '{for(i=1;i<=NF;i++){print $i}}' passwd
awk数组
将需要统计的某个字段作为数组的索引,然后对索引进行遍历 #统计数组 (把最后一列作为索引) [root@shell01 ~]# awk -F: '{shell[$NF]++}' /etc/passwd #计算次数 [root@shell01 ~]# awk -F: '{shell[$NF]++}END{for(i in shell)print i"出现了"shell[i]"次"}' /etc/passwd /bin/sync出现了1次 /bin/bash出现了1次 /sbin/nologin出现了20次 /sbin/halt出现了1次 /sbin/shutdown出现了1次 #站访问状态统计 [root@shell01 shell13]# ss -an Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port nl UNCONN 0 0 0:0 * nl UNCONN 0 0 0:5717 * nl UNCONN 0 0 0:5717 * nl UNCONN 4352 0 4:7971 * [root@shell01 ~]# ss -an|awk '{status[$2]++}END{for(i in status)print i,status[i]}' LISTEN 38 ESTAB 90 State 1 UNCONN 63
标签:语句,10,passwd,shell01,awk,print,root,shell13 From: https://www.cnblogs.com/ludingchao/p/18227774