这篇文章上次修改于 1705 天前,可能其部分内容已经发生变化,如有疑问可询问作者。
Awk
Awk简介
Awk是一种编程语言,可以在Linux下对文本和数据进行扫描与处理,数据可以来自标准输入、文件、管道。
Awk工作流程
- 逐行扫描文件 --> 从第一行到最后一行 --> 寻找匹配特定模式的行 --> 进行用户操作
Awk的两个特殊模式:
- BEGIN模式:awk将在读取任何输入行之前执行BEGIN中的操作。
END模式:awk将在正式退出之前执行END中的操作。
Awk基本语法格式
gawk [选项] -f program-file [--] file ...
POSIX options: GNU long options: (standard) -f progfile --file=progfile -F fs --field-separator=fs -v var=val --assign=var=val Short options: GNU long options: (extensions) -b --characters-as-bytes -c --traditional -C --copyright -d[file] --dump-variables[=file] -e 'program-text' --source='program-text' -E file --exec=file -g --gen-pot -h --help -L [fatal] --lint[=fatal] -n --non-decimal-data -N --use-lc-numeric -O --optimize -p[file] --profile[=file] -P --posix -r --re-interval -S --sandbox -t --lint-old -V --version
Awk操作指令
记录与字段
Awk一次从文件中读取一条记录,并将记录存储在字段变量$0中。记录为分割为字段并存储在$1,$2,...,$NF中(默认使用空格或制表符为分隔符)。
#读取输入行,并输出第一个字段、第二个字段、第三个字段 [root@Hyui-VM ~]# echo hello the world | awk '{print $1,$2,$3}' hello the world #读取输入行,直接输出该行 [root@Hyui-VM ~]# echo hello the world | awk '{print $0}' hello the world #输出该行的字段个数 [root@Hyui-VM ~]# echo hello the world | awk '{print NF}' 3 #输出该行最后一个字段 [root@Hyui-VM ~]# echo hello the world | awk '{print $NF}' world
字段分隔符
Awk默认使用空格和制表符作为分隔符,使用-F和FS可以改变分隔符。
[root@Hyui-VM ~]# awk -F: '{print $1}' /etc/passwd [root@Hyui-VM ~]# awk 'BEGIN {FS=":"} {print $1}' /etc/passwd
- 以上两种方法都是将":"设定为分隔符,以":"为分隔符打印passwd文件的第一个字段。
如何指定多个字段分隔符?
[root@Hyui-VM ~]# echo 'hello the:world,!' | awk 'BEGIN {FS="[:,]"} {print $1,$2,$3,$4}' hello the world !
内置变量
变量列表
变量名称 描 述 ARGC 命令行参数个数 FILENAME 当前输入文档名称 FNR 当前输入文档当前记录编号 NR 输入流的当前记录编号 NF 当前记录的字段个数 FS 字段分隔符 OFS 输出字段分隔符,默认为空格 ORS 输出记录分隔符,默认换行符\n RS 输入记录分隔符,默认为\n 示例1
[root@Hyui-VM ~]# cat neko.html <html> <title>Neko Site</title> <body> h1Cute Nekoh1 h2Kawaii Nekoh2 h3Yasashi Nekoh3 </body> </html> [root@Hyui-VM ~]# cat network DEVICE=eno16777736 onboot=yes BOOTPROTO=static ipaddr=192.168.0.1 nEtMaSt=255.255.255.0 GaTeWaY=192.168.0.254
输出当前文档的当前编号,第一个文件有8行,第二个文件有6行。
[root@Hyui-VM ~]# awk '{print FNR}' neko.html network 1 2 3 4 5 6 7 8 1 2 3 4 5 6
将两个文档作为一个整体输入流,通过NR输入当前编号。
[root@Hyui-VM ~]# awk '{print NR}' neko.html network 1 2 3 4 5 6 7 8 9 10 11 12 13 14
文档每行的字段数量。
[root@Hyui-VM ~]# awk '{print NF}' neko.html 1 2 1 2 2 2 1 1
示例2
通过OFS将输出分隔符设置为"-"。
[root@Hyui-VM ~]# cat test.txt This is a test file. Welcome to CentOS Linux 7.
root@Hyui-VM ~]# awk 'BEGIN {OFS="-"} {print $1,$2,$3}' test.txt This-is-a Welcome-to-CentOS
表达式与操作符
操作符示例
[root@Hyui-VM ~]# echo "test" | awk 'x=2 {print x+3}' 5
9
输出sshd_config所有空白行
[root@Hyui-VM ~]# awk '/^$/ {print x+=1}' /etc/ssh/sshd_config
1
2
3
4
5
......[省略]输出sshd_config总空白行个数
[root@Hyui-VM ~]# awk '/^$/ {x+=1} END {print x}' /etc/ssh/sshd_config
27列出passwd的id大于500的用户名
[root@Hyui-VM ~]# awk -F: '$3>500 {print $1}' /etc/passwd
polkitd
chrony## Awk高级应用
格式:
if (表达式) 动作1 else 动作2 if (表达式) 动作1; else 动作2
判断vda1可用存储是否不足2G
[root@Hyui-VM ~]# df | grep vda1 | awk '{if($4<2000000) Print "Insufficient storage"; else print "OK"}' OK
While循环
格式1:
while(条件) 动作
示例:
[root@Hyui-VM ~]# awk 'i=1 {} BEGIN {while(i<=5){++i; print i}}' neko.html 1 2 3 4 5 6
格式2:
do 动作 while(条件)
示例:
[root@Hyui-VM ~]# awk 'BEGIN { do {++x; print x} while (x<=5)}' neko.html 1 2 3 4 5 6
For循环
for (变量;条件;计数器) 动作
示例:
[root@Hyui-VM ~]# awk 'BEGIN {for (i=1;i<=5;i++) print i}' neko.html 1 2 3 4 5
函数
rand()函数
- 作用:产生0~1之间的浮点类型随机数。
示例:
[root@Hyui-VM ~]# awk 'BEGIN{print rand(); srand(); print srand()}' test.txt 0.237788 1585732218
使用srand()使每次产生的随机数不同
gsub(x,y,z)函数
作用:在字串z中使用字串y替换与正则表达式x相匹配的所有字串,z默认为$0。
sub(x,y,z)函数
作用:在字串z中使用字串y替换与正则表达式x相匹配的di'yi'g字串,z默认为$0。
[root@Hyui-VM ~]# awk -F: 'gsub(/root/,"centos",$0) {print $0}' /etc/passwd centos:x:0:0:centos:/centos:/bin/bash operator:x:11:0:operator:/centos:/sbin/nologin [root@Hyui-VM ~]# awk -F: 'sub(/root/,"centos",$0) {print $0}' /etc/passwd centos:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/centos:/sbin/nologin
length(z)函数
作用:计算并返回字串长度。
[root@Hyui-VM ~]# awk '{print length()}' test.txt 20 26
getline函数
作用:从输入中读取下一行内容。
[root@Hyui-VM ~]# df -h Filesystem Size Used Avail Use% Mounted on devtmpfs 1.9G 0 1.9G 0% /dev tmpfs 1.9G 0 1.9G 0% /dev/shm tmpfs 1.9G 424K 1.9G 1% /run tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup /dev/vda1 40G 2.1G 36G 6% / tmpfs 379M 0 379M 0% /run/user/0
[root@Hyui-VM ~]# df -h | awk '{if(NF==1) {getline; print $3}; if(NF==6) print $4}' 1.9G 1.9G 1.9G 1.9G 36G 379M
没有评论