AWK的叫法来源于其三位创始人姓氏首字母,需要注意的是,我们现在使用的awk其实多为gawk(基于GNU项目的awk的实现方式,除了正常的awk功能还额外提供了一些扩展):
AWK默认以换行符为标记对文本进行逐行处理,那么尤其那些每行格式相同的文本文件,用AWK来格式化数据输出的时候会非常方便。所以人们常说AWK擅长处理列。
- 基本语法
awk [OPTION] 'Pattern{Action}' file
其中Pattern表示AWK在数据中查找的内容,而Action是在找到匹配内容时所执行的一系列命令。我们通过举例来说明他们的用法。
最常用的OPTION举例
以下是比较实用的一些参数,其他使用频率低的参数感兴趣的话可以看看man手册。
参数 | 功能 |
---|---|
-F | 自定义分隔符,太实用了 |
-f | 指定awk脚本,可以提前将'Pattern{Action}'写好 |
最常用的Action举例
- 单纯打印文件内容
[root@localhost ~]# awk '{print}' /etc/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 adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync ...
- 提取第1列
[root@localhost ~]# awk -F : '{print $1}' /etc/passwd root bin daemon adm lp sync ...
输出结果是按冒号(默认是空格或制表符作为分隔符,而且会自动将连续空格理解为1个分割单位)进行分割。此处还使用了内置变量:$1表示第一列,$0表示所有列(整行),$NF表示最后一列,$(NF-1)就可以表示倒数第二列。
- 实现提取结果拼接自定义字符串
[root@localhost ~]# awk -F : '{ print "user:"$1}' /etc/passwd user:root user:bin user:daemon user:adm user:lp user:sync ...
- 打印结果时调用内置函数
这里我们介绍几个最常用的函数,大小写转换toupper/tolower,按长度(从m到n)进行截取substr(s,m,n) :
[root@localhost ~]# awk -F : '{ print toupper($1)}' /etc/passwd ROOT BIN DAEMON ADM LP SYNC ... [root@localhost ~]# awk -F : '{ print substr($1,1,2)}' /etc/passwd ro bi da ad lp sy ...
常用的Pattern举例
- BEGIN模式
该模式指定了处理文本之前需要执行的操作,常用来初始化变量:
[root@localhost ~]# awk -F : 'BEGIN{printf "NAME PASSWD\n"} {print $1,$2}' /etc/passwd NAME PASSWD root x bin x daemon x adm x lp x sync x ...
- END模式
模式指定了处理完所有行之后所需要执行的操作:
[root@localhost ~]# awk -F : 'BEGIN{print "NAME PASSWD";count=0} {print $1;count = count + 1} END{printf "行数总计: %d\n",count}' /etc/passwd NAME PASSWD root bin daemon adm lp sync shutdown halt mail operator games ftp nobody systemd-network dbus polkitd sshd postfix dhcpd apache tss chrony geoclue 行数总计: 23 [root@localhost ~]#
- 匹配模式
通过正则表达式(awk支持的ERES扩展的正则表达式)实现过滤,如匹配含有字符串bash的行:
[root@localhost ~]# awk '/bash/ {print $0}' /etc/passwd root:x:0:0:root:/root:/bin/bash [root@localhost ~]#
- 条件模式
通过设置条件实现过滤,如匹配奇数行:
[root@localhost ~]# awk 'NR % 2 == 1 {print "line_num:"NR,$0}' /etc/passwd line_num:1 root:x:0:0:root:/root:/bin/bash line_num:3 daemon:x:2:2:daemon:/sbin:/sbin/nologin line_num:5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin ...
其他
再强大的命令,只有和其他命令结合,才能变得更加实用。awk可以将输出作为其他命令的参数,使用管道即可:
[root@localhost ~]# awk 'BEGIN { print "hello" | "tr [a-z] [A-Z]" }' HELLO [root@localhost ~]#
评论列表,共 0 条评论
暂无评论