linux 之 awk (1)

112 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第8天,点击查看活动详情

1. wiki

awk 可以理解一种编程语言,其对输入数据的每一行都进行文本处理,并内建一些数据结构和函数,在熟悉者手中十分灵活

2. 语法

基本语法框架为,其由选项、脚本和输入的数据等组成

awk [options] '[scripts]' [files]

1. options

常用的选项主要有 3 个,更多选项可以使用 --help 查看

  • -f [progfile] , --file=[progfile] : 从脚本文件 progfile 中读取事先写好的 awk 命令
  • -F [fs] , --field-separator=[fs] : 指定输入中的分隔符,fs 可以是字符串或正则表达式,特殊字符可以使用转义
  • -v [var=value] , --asign=[var=value] : 给自定义变量赋值,将外部变量传递给 awk

2. scripts

基本语法结构为,脚本通常由模式和命令两部分组成,可以省略其一,但不能同时被省略,其包裹在单引号 '' 或双引号 "" 中。注意,与 shell 的用法一致,在使用单引号 '' 时,变量不会被解释,双引号 "" 中变量则会被替换成相应结果

pattern{commands}

1. 模式

模式可以是很多种,一般情况下,每碰到一个使模式表达式为真的输入行,命令就会执行

  • 正则表达式 : 语法为 /r/,支持常用的通配符,也可以使用 exp ~ /r/exp !~ /r/ 显示表达匹配和不匹配
  • 逻辑表达式 : 大于、小于、等于、且、或、否等
  • BEGIN{} : 特殊模式,其不匹配任何输入行,只在开头执行一次,一般用作变量初始化、打印输表头等操作
  • END{} : 特殊模式,其不匹配任何输入行,只在结束执行一次,一般用来打印结果等操作
# 读取 : 分隔的文件 passwd,取以 root 或 ftp 开头的行,并打印
awk -F : '/^root|^ftp/{print}' /etc/passwd
# 读取 | 分隔的文件 output.log,取行号大于 3 的行,并打印第行号和第一个字段
awk -F \| 'NR > 3{print NR,$1}' output.log

2. 命令

命令支持很多形式,包括变量或数组赋、内置函数、控制流语句等,其格式也有一定要求:

  • 一行可包含若干条语句,使用分号分开即可
  • 命令的左花括号必须与它的模式在同一行,空行会被忽略
  • 注释可以出现在任意一行的末尾,一个注释以井号 (#) 开始,以换行符结束
  • 一条长语句可以分散成多行,只要在断行处插入一个反斜杠即可

3. 内建变量

awk 会统计一些元数据信息,并存入内建变量中,常用的有

  • $0 : 完整的输入记录
  • $n : 当前记录的由 FS 分隔的第 n 个字段,如 $1 表示第一个字段
  • FS : 字段分隔符,默认是任一空格
  • NR : 表示记录数,在执行过程中对应于当前的行号
  • NF : 表示字段数,在记录被读之后重置为1,如 $NF 为最后一个字段
  • FNR : 同 NR,但相对于当前文件
  • FILENAME : 当前输入文件的名

其他变量的详情,可以使用 man awk 来查看,也可以使用命令 awk --dump-variables '',会将部分可用的变量输出到 awkvars.out 文件中,

  • ARGC : 命令行参数的数目。
  • ARGV : 命令行参数数组
  • ARGIND : 命令行中当前文件的位置,主要针对多个文件的输入
  • CONVFMT : 数字转换格式,默认值为 %.6g
  • ERRNO : 最后一个系统错误的描述
  • FIELDWIDTHS : 字段宽度列表,用空格分隔
  • FNR : 同 NR,但相对于当前文件
  • IGNORECASE : 为真,则进行忽略大小写的匹配,默认为假
  • OFMT : 数字的输出格式,默认为 %.6g
  • OFS : 输出字段分隔符,默认为空格
  • ORS : 输出记录分隔符,默认为换行符
  • RS : 记录分隔符,默认为换行符
  • RLENGTH : 由 match 函数所匹配的字符串的长度
  • RSTART : 由 match 函数所匹配的字符串的第一个位置
  • SUBSEP : 数组下标分隔符,默认为 \034