温故而知新,今天来温习下awk工具

概述

  • awk是一个优良的文本处理工具,Linux及Unix环境中现有的功能最强大的数据处理引擎之一。awk经过改进生成的新的版本nawk,gawk,现在默认linux系统下日常使用的是gawk
    在这里插入图片描述
  • awk功能:可以进行样式装入、流控制、数学运算符、进程控制语句甚至于内置的变量和函数
  • 在awk 中两个特别的表达式:BEGIN和END。这两者都可用于pattern中,提供BEGIN和END的作用是给程序赋予初始状态和在程序结束之后执行一些扫尾的工作。任何在BEGIN之后列出的操作(在{}内)都将在awk开始扫描输入之前执行,而END之后列出的操作都将在扫描完全部的输入之后执行。因此,通常使用BEGIN来显示变量和预置(初始化)变量,使用END来输出最终结果

工作原理

  • 逐行读取文本,默认以空格或tab键分隔符进行分隔,将分隔所得的各个字段保存到内建变量中,并按模式或者条件执行编辑命令
  • sed命令常用于一整行的处理,而awk命令则比较倾向于将一行分成多个“字段”然后再进行处理
  • awk信息的读入也是逐行读取的,执行结果可以通过print的功能将字段数据打印显示
  • 在使用awk命令的过程中,可以使用逻辑操作符“&&”表示“与”的意思,“||”表示“或”的意思,“!”表示“非,不”的意思;还可以进行简单的数学运算,如“+”、“-”、“*”、“/”、“%”、“^”分别代表加、减、乘、除、取余和乘方的意思

命令格式

  • awk 选项 '模式或条件 {操作}'文件1 文件2…
  • awk -f 脚本文件 文件1 文件2 …
    在这里插入图片描述

awk常见的内建变量(可直接使用)如下表格所示

变量 说明
FS 列分隔符
指定每行文本的的字段分隔符,默认为空格或制表符,与“-F”作用相同
RS 行分隔符
awk从文件上读取资料时,将根据RS的定义把资料切割成许多条记录,而awk一次仅读入一条记录以进行处理。预设值是’\n’
NF 当前处理行的字段个数
NR 当前处理行的行号(序数)
$0 当前处理行的整行内容
$n 当前处理行的第n个字段(第n列)
FILENAME 被处理的文件名

常见的内建变量命令图释

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

按字段输出文本(命令剖析)

[root@localhost ~]# awk -F ":" '!($3<200) {print $1,$3}' /etc/passwd
【输出第3个字段的值不小于200的行中第1个和第3个字段内容】
polkitd 999
libstoragemgmt 998
colord 997
saslauth 996
chrony 995
nfsnobody 65534
geoclue 994
setroubleshoot 993
sssd 992
gnome-initial-setup 991
qz 1000
[root@localhost ~]# awk -F ":" '$3<6{print $1,$3}' /etc/passwd
【输出第3个字段的值小于6的第1个和第3个字段内容】
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
[root@localhost ~]# awk -F ":" '{print $1,$3}' /etc/passwd
【输出每行中的第1个和第3个字段】
root 0
bin 1
......
......
postfix 89
tcpdump 72
qz 1000
[root@localhost ~]# awk -F "/" '{print $2}' /etc/passwd
【输出每行中以“/”分隔的第2个字段】
root:
bin:
......
......
var
:
home
[root@localhost ~]# awk -F ":" '{print $1}' /etc/passwd
【输出每行中以“:”分隔的第1个字段】
root
bin
......
......
qz
[root@localhost ~]# awk 'BEGIN {FS="/"};{if($3>1000){print$2,$3}}' /etc/passwd
【先处理完BEGIN的内容,将每行中的默认分隔符更换成以“/”分隔,再打印出当第3列值小于1000的行中的第2列和第3列内容】
root: bin
bin: sbin
......
......
var spool
: sbin
home qz:
[root@localhost ~]# awk -F ":" '{qz=($3>=$4)?$3:$4;{print qz}}' /etc/passwd
【($3>=$4)?$3:$4是三元运算符,如果第3个字段的值≥第4个字段的值,则把第3个字段的值赋给qz,否则把第4个字段的值赋给qz,
最后打印出被赋值后的变量qz
“?”代表当前面“$3>=$4”条件成立则输出"?"后面的语句
":"代表当前面“$3>=$4”条件不成立则输出":"后面的语句】
0
1
2
......
......
72
1000
[root@localhost ~]# awk -F ":" '$7~"/bash"{print $1}' /etc/passwd
【输出以冒号分隔且第7个字段中包含/bash的行里的第1个字段】
root
qz
[root@localhost ~]# awk -F ":" '{print NR,$0}' /etc/passwd
【输出内容的内容和行号。每次处理完一条记录,NR的值都会加11 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
......
......
40 tcpdump:x:72:72::/:/sbin/nologin
41 qz:x:1000:1000:qz:/home/qz:/bin/bash
[root@localhost ~]# awk -F ":" '($1~"root")&&(NF==7){print $1,$2}' /etc/passwd
【输出第1个字段中包含root字符且共有7个字段的行里面的第1个和第2个字段】
root x
[root@localhost ~]# awk -F ":" '($7!="/bin/bash")&&($7!="/sbin/nologin"){print}' /etc/passwd
【输出第7个字段中即不为/bin/bash也不是/sbin/nologin字符的所有行】
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt

通过管道符号、双引号调用Shell命令

[root@localhost ~]# echo $PATH | awk 'BEGIN{RS=":"};END{print NR}'
【先echo出$PATH的内容,然后统计以“:”分隔的文本段落数,END{
    
    }语句块中,通常会放入打印结果等语句】
5
[root@localhost ~]# echo $PATH 
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@localhost ~]# awk -F: '/nologin$/{print | "wc -l"}' /etc/passwd
【调用“wc -l”命令统计以nologin结尾的用户个数,等同于grep -c "nologin$"36
[root@localhost ~]# grep -c "nologin$" /etc/passwd
36

查看当前内存空闲率和CPU使用率以及重启时间

[root@localhost ~]# top -b -n 1 | grep Cpu | awk -F ',' '{print $4}' | awk '{print $1}'
【查看当前CPU空闲率,(-b -n 1表示只需要1次的输出结果)】
100.0
[root@localhost ~]# free -m | awk '/Mem:/{print int($3/($3+$4)*100)"%"}'
【查看当前内存使用百分比】
21%
[root@localhost ~]# date -d "$(awk -F "." '{print $1}' /proc/uptime) second ago" +"%F %H:%M:%S"
2021-03-16 08:44:48
[root@localhost ~]# init 6
[root@localhost ~]# date -d "$(awk -F "." '{print $1}' /proc/uptime) second ago" +"%F %H:%M:%S"
2021-03-16 11:30:16
【显示系统上次系统重启时间,等同于uptime;second ago为显示多少秒前的时间;+"%F %H:%M:%S"等同于+"%Y-%M-%D %H:%M:%S"的时间格式】

统计在线用户数与当前主机名

[root@localhost ~]# awk 'BEGIN {q=0;while ("w" | getline)q++;{print q-2}}'
1
[root@localhost ~]# awk 'BEGIN {q=0;while ("w" | getline)q++;{print q-2}}'
2
[root@localhost ~]# awk 'BEGIN {q=0;while ("w" | getline)q++;{print q-2}}'
3
【调用w命令来统计当前在线用户数】
[root@localhost ~]# awk 'BEGIN {"hostname" | getline;{print $0}}'
localhost.localdomain
【调用hostname命令输出当前的主机名】
[root@localhost ~]# hostname
localhost.localdomain
[root@localhost ~]# seq 5 | awk '{getline;print $0}'
2
4
5
[root@localhost ~]# seq 5 | awk '{print $0;getline}'
1
3
5
【当getline左右无重定向符“<”或“|”时,awk首先读取到第一行,就是1,然后getline就得到了1下面的第二行,就是2.因为getline
之后,awk会改变对应的NF、NR、FNR和$0等内部变量,所以此时的$0的值就不再是1,而是2了,然后将它打印出来】
【当getline左右有重定向符“<”或“|”时,getline则作用于定向输入文件,由于该文件是刚打开,还没有被awk读入一行,只是getline
读入,所以getline返回的则是该文件的第一行,而不是隔行】

猜你喜欢

转载自blog.csdn.net/TaKe___Easy/article/details/114867042