--- title: "awk 命令" date: 2019-10-30T00:47:01+08:00 lastmod: 2019-10-30T00:47:01+08:00 keywords: [] tags: ["awk"] categories: ["shell"] --- ## 格式 - awk -F '分隔符正则' -v 变量名=值 'BEGIN{动作} 条件{动作} END{动作}' 文件1 文件2 ... - awk -F '分隔符正则' -f awk脚本文件名 文件1 文件2 ... ## 常用内置变量 变量 | 说明 ---- | ---- $0 | 当前记录 $1~$n | 当前记录的第n个字段,字段间由FS分隔 FS | 输入字段分隔符 默认是空格 NF | 当前记录中的字段个数,就是有多少列 NR | awk 开始执行程序后所读取的数据行数,就是行号,从1开始 RS | 输入的记录他隔符默 认为换行符 OFS | 输出字段分隔符 默认也是空格 ORS | 输出的记录分隔符,默认为换行符 FNR | 当前记录数,awk每打开一个新文件,FNR便从0重新累计 ARGC | 命令行参数个数 ARGV | 命令行参数字典,ARGV[0] 是 'awk',ARGV[1] 是 FILENAME FILENAME | 当前输入文件的名字 IGNORECASE | 如果为真,则进行忽略大小写的匹配 ENVIRON | UNIX环境变量,如 ENVIRON["PATH"] FIELDWIDTHS | 输入字段宽度的空白分隔字符串 OFMT | 数字的输出格式(默认值是%.6g) RSTART | 被 match 匹配函数匹配的字符串位置 RLENGTH | 被 match 匹配函数匹配的字符串长度 ## 函数 ### 常用内置函数 函数 | 说明 ---- | ---- int(x) | 返回 x 的整数部分 rand() | 返回 0 到 1 之间的浮点数 gsub(Ere, "dest", str) | 把 str 中匹配扩展正则 Ere 的全部子串换成字符串 "dest" sub(Ere, "dest", str) | 把 str 中匹配扩展正则 Ere 的第一个子串换成字符串 "dest" substr(str, start, len) | 返回 str 中从 start 开始(长度为 len )的子串 index(str1, str2) | 返回 str1 中出现 str2 的位置,如果未找到,返回 0 length(str) | 返回 str 的字符个数,如果未指定 str,返回 $0 包含字符个数 blength(str) | 返回 str 的字节个数,如果未指定 str,返回 $0 包含字节个数 match(str, Ere) | 返回 str 中匹配扩展正则 Ere 的位置,如果未找到,返回 0 split(str, arr, Ere) | 把 str 按照扩展正则 Ere 切分成字典,存储到 arr 中,返回字典长度 tolower(str) | 把 str 换成小写 toupper(str) | 把 str 换成大写 sprintf("%s-%d", "abcd", 1234) | 返回 abcd-1234 strtonum(str) | 返回十进制数字 delete arr[n] | 删除字典/字典的对应元素 getline | 读入当前行的下一行,重写变量 0 next | 停止处理当前记录,开始处理下一行 nextfile | 停止处理当前文件,开始处理下一个文件 system(shell-command) | 返回命令退出状态 exit n | 终止 awk,返回 n ### 自定义函数 - 格式 ```awk function fun_name(arg1, arg2, ...){ #函数体 return } ``` ## 判断语句 - if ```awk if(条件){ # 语句 }else if(条件){ # 语句 }else{ # 语句 } ``` ## 循环语句 - for ```awk for(初始化;条件;变化){ # 语句 } for(变量 in 字典){ # 语句 } ``` - while ```awk while(条件){ # 语句 } ``` - do while ```awk do{ # 语句 }while(条件) ``` - break 退出当前循环体 - continue 退出本次循环,继续下一次循环 ## 脚本 ```awk #!/usr/bin/awk -f # 自定义的变量和函数 # ... # 从这里开始执行 BEGIN{ # 语句 } 条件{ # 语句 } END{ # 语句 } ``` ## 其他说明 - 变量在使用时直接赋值即可,无需提前声明或定义 - 个人认为,awk 没有数组只有字典,数组是键为整数的字典 - 运算符(+, -, \*, /, ++, -- 等)和关系符操作(>, >=, <, <=, ~, !~ 等)与 C 基本一致,也支持三目运算符(条件?值1:值2) - shell 中 awk 执行显式命令时,加载 shell 中的变量 ```bash #!/bin/bash shell_value='abcd' echo | awk '{print "'$shell_value'"}' # 输出 abcd ``` ## 参考 - man awk - [其他内置函数](https://www.gnu.org/software/gawk/manual/html_node/Built_002din.html#Built_002din) - [gnu awk 手册](https://www.gnu.org/software/gawk/manual/gawk.html)