相关文章推荐
  1. 1. 简介
  2. 2. 程序格式
  3. 3. 简单输入实验
  4. 4. 模式
    1. 4.1. BEGIN/END模式
    2. 4.2. 表达式模式
    3. 4.3. 组合模式
    4. 4.4. 范围模式
  5. 5. 动作
    1. 5.1. 变量
      1. 5.1.1. 内置变量
      2. 5.1.2. 字段变量
    2. 5.2. 函数
      1. 5.2.1. 算术函数
      2. 5.2.2. 字符串函数
    3. 5.3. 流程控制语句
  6. 6. 参考

Awk是Linux系统中强大的文本处理命令工具。它名字来源于它的创始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首个字母。Awk是一个工具,也是一种程序语言,类似c语言,但无需提前进行变量声明定义。一个Awk程序由一系列的模式(pattern)和动作(action)组成, 模式用于描述在输入的文本中搜索哪些数据, 当某一行文本搜索到(即匹配某个模式)之后,动作定义了如何操作该行文本。

一个awk程序格式如下:

pattern { action }

awk的操作逻辑是扫描文本每一行, 搜索可以被模式(pattern)匹配的行, 若行能够匹配模式,则接着进行执行动作(action)。

在扫描每一行过程中,awk会自动把当前行分解为一个个的字段,默认是空格进行分割,$0表示当前行内容,$1为当前行的第一段,$2为当前行的第二段,以此类推。

简单输入实验

下面我们进行实例说明,假定有如下职工信息文件emp.data,每一列分别代表是年龄 性别 工作天数 日薪:

张三    20  M 20 100
李四    30  M 15 120
王大锤  22  M 18 150
张爱花   24 F 22 130
李丽    22 F  21 160
李甜甜  21  F 20 122

我们想打印每位男性职工姓名和月薪,只需要下面一行:

awk '$3 == "M" {print $1, $4 * $5}' emp.data

将输入一下内容:

张三 2000
李四 1800
王大锤 2700

其中$3=="M" 是pattern, print $1, $4* 5是action,两者通过大括号分开。print用于打印数据,且以换行符结束。在print语句中由逗号分隔的表达式, 在输出时默认用一个空格符分隔。

正如上面展示那样我们运行一个awk程序需要如下这样:

1
awk awk程序 文本文件

当然awk也支持同时处理多个文件:

1
awk awk程序 文本文件1 文本文件2

如果awk程序内容较长,我们可以把程序放在一个独立的文件中:

1
awk -f awk程序文件 文本文件

在详解讲解模式和动作之前,我们来进行一些简单的练习:

  • 打印所有行
  • awk ‘{print $0}’ emp.data

    如果一个动作没有模式, 对于每一个输入行, 该动作都会被执行。此处的$0可以省略。等效于

    awk ‘{print}’ emp.data

  • 打印某些字段,这里是姓名和年龄
  • awk ‘{print $1,$2}’ emp.data

  • 打印月薪超过2000的员工
  • awk ‘$4 * $5 >2000 {print $1, $4*$5}’ emp.data

    awk模式大致可以分5大类,上面我们使用的都是常规表达式模式,此外还有正则表达式模式,BEGIN/END模式,组合模式,范围模式。

    BEGIN/END模式 BEGIN{ statements}或 END{ statements} BEGIN将在输入被读取之前, statements 执行一次, END会当所有输入被读取完毕之后, statements执行一次 常规表达式模式 expression { statements} 每碰到一个使 expression 为真的输入行, statements 就执行. expression 为真指的是其值非零或非空 正则表达式模式 /regular expression/ { statements} 当碰到这样一个输入行时, statements 就执行: 输入行含有一段字符串, 而该字符串可以被 regular expression 匹配 compound pattern { statements} 一个复合模式将表达式用 &&(AND), (OR), !(NOT), 以及括号组合起来; 当 compound pattern 为真时, statements 执行 pattern1, pattern2 { statements} 一个范围模式匹配多个输入行, 这些输入行从匹配 pattern1 的行开始, 到匹配的行结束 (包括这两行), 对这其中的每一行执行 statements

    BEGIN/END模式

    BEGIN/END是唯一不能省略动作的模式。

  • 在打印所有行之前,先打印一个信息头:
  • awk ‘BEGIN{print “员工基本信息与薪资情况表:”; print “”}{print}’ emp.data

    上面命令将输出一下内容:

    员工基本信息与薪资情况表:
    张三    20  M 20 100
    李四    30  M 15 120
    王大锤  22  M 18 150
    张爱花   24 F 22 130
    李丽    22 F  21 160
    李甜甜  21  F 20 122
    
  • 统计月工作时间超过20天的员工数:
  • awk ‘$4>20 {num++} END{print num"个人月工作时间超过20天"}’ emp.data

    上面命令输出:

    2个人月工作时间超过20天

    num是awk自定义变量,print打印内容时候,字符串会自动拼接起来。

    表达式模式

    在awk中,任意一个表达式都可以当作模式来使用。如果一个作为模式使用的表达式, 对当前输入行的求值结果非零或不为空, 那么该模式就匹配该行。典型的表达式模式是那些涉及到数值或字符串比较的表达式。 一个比较表达式包含 6 种关系运算符中的一种, 或者包含两种字符串匹配运算符中的一种: ~ 与 !~

    关系运算符列如下表:

    在一个关系比较中, 如果两个操作数都是数值, 关系比较将会按照数值比较进行; 否则的话,数值操作数会被转换成字符串, 再将操作数按字符串的形式进行比较. 两个字符串间的比较以自然排序的方式进行比较。

    查看员工王大锤的信息,我们可以使用表达式模式

    awk ‘$1==“王大锤” {print $0}’ emp.data

    输入以下内容:

    王大锤  22  M 18 150
    

    除了常规的表达式之外,awk还支持正则表达式模式,来测试一个字符串是否包含一段可以被正则表达式匹配的子字符串。当然严格的来讲正则表达式模式是表达式模式的一种。正则表达式模式常用于字符串比较,也称为字符串匹配模式。

    有三种字符串匹配模式:

    由于正则表达式内容比较多,这就不在详细介绍正则表达式了。可以自行去《正则表达式30分钟入门教程》学习。

    模式通过括号, 逻辑运算符 ||(OR), &&(AND),!(NOT) 进行组合,就构成一个组合模式。运算符 || 优先级最低, 再往高是 &&, 最高的是 !。 && 与 || 从左至右计算操作数的值, 一旦已经知道整个表达式的值, 计算便停止

    比如我们想统计李姓女性员工信息:

    awk ‘$1 ~ /李/ && $3 == “F” {print $0}’ emp.data

    上面程序将会输出:

    李丽    22 F  21 160
    李甜甜  21  F 20 122
    

    一个范围模式由两个被逗号分开的模式组成, 正如

    	pattern1, pattern2
    

    一个范围模式匹配多个输入行, 这些输入行从匹配 pattern1 的行开始, 到匹配 pattern2 的行结束(包括这两行);如果范围模式的第二个模式一直都没有匹配到某个输入行, 那么范围模式会一直匹配到输入结束。pattern2可以与 pattern1可以匹配到同一行。

    我们拿下面的例子做说明,我们想王大锤到李丽的员工信息:

    awk ‘$1 == “王大锤”, $1 == “李丽” {print $0}’ emp.data

    上面程序将输出以下内容:

    王大锤  22  M 18 150
    张爱花   24 F 22 130
    李丽    22 F  21 160
    

    动作描述了输入行被搜索匹配到之后,接下来该如何操作。构成动作的语句可以是表达式或者流程控制语句,比如if/where/for等语句。

    表达式语句可以简单到只有一个print,也可以是变量,赋值,函数调用。

    awk里面变量可以分三类:用户自定义变量(user defined variables)、内置变量(Built-In Variables)、字段变量(Field Variables)。一个未初始化的变量的值是 “” (空字符串) 与 0。

    下面是使用自定义变量统计职工总数的例子:

    awk ‘{emp =emp+1} END{print "总共人数:"emp}’ emp.data

    下面内置变量列表:

    字段变量 (Field Variables). 当前输入行的字段从 $1, $2, 一直到 $NF; $0 表示整行. 字段变量与其他变量相比没什么不同 — 它们也可以用在算术或字符串运算中, 也可以被赋值。

    下面语句将打印每一行内容,并加上行号:

    awk ‘{ print NR “:” $0 }’ emp.data

    打印出内容如下:

    1:张三    20  M 20 100
    2:李四    30  M 15 120
    3:王大锤  22  M 18 150
    4:张爱花   24 F 22 130
    5:李丽    22 F  21 160
    6:李甜甜  21  F 20 122
    

    awk变量类型分为两类,数字和字符串。awk内置的函数有算术函数((Built-In Arithmetic Functions)和字符串函数(

    算术函数列表有:

    if (expression) statements1 else statements2
    如果 expression 为真, 执行 statements1, 否则执行 statements2

    while (expression) statements
    如果 expression 为真, 执行 statements; 然后重复前面的过程

    for (expression1;expression2;expression3 ) statements
    等价于 expression1; while (expression2) { statements; expression3}

    for (variable in array) statements
    轮流地将 variable 设置为 array 的每一个下标, 并执行 statements

    do statements while (expression)
    执行 statements; 如果 expression 为真就重复

    下面分别使用while和for来打印每个字段信息:

    while:

    { i = 1
    while (i <= NF) {
            print $i
    
    { for (i = 1; i <= NF; i++)
        print $i
    

    do-while:

    i = 1 print $i } while (i++ < NF)
  • AWK 程序设计语言
  • 12-factor 2FA API API网关 Ansible Awk CSRF Cheat Sheet Consul Coredns Data Science Debounce Devops Docker Elasiticsearch小技巧 Elasticsearch优化 Elasticsearch内存占用 GDB GMP模型 Golang Go通道 HTTP HTTP Cache HTTP协议 HTTP状态码 JAVASCRIPT Jupyter notebook Linux命令 Linux命令大全 Linux配置 Logrotate Lua Nginx Opcache PHP PHP-FPM PHP优化 Pandas Prometheus QPS RESTful Redis Redis主从复制 Redis系统服务 SQL注入 SSH Systemd Throttle Webgrind Web安全 Wireshark XSS Xdebug context docker golang golang defer grpc iptables k8s nat netstat nil通道 protobuf pyspark python spark sublime sublime插件 tmux tow-factor authentication 东西流量 人生 代理 代码模式 代码质量 供给侧 函数选项 分布式 分布式ID 分析 南北流量 原创翻译 原子操作 双因素认证 反射 反射三定律 取模运算 吞吐量 完全指南 年度回顾 并发数 并发编程 微服务 性能优化 性能优化工具 性能指标 技术分享 持续集成 持续集成工具 效率神器 数学证明 日志管理 时区 服务发现 服务网格 格言 汇编 爱情 程序内存布局 算法 终端复用 统计学 统计思维 翻译 自动化部署 自旋锁 营改增 设计模式 调试工具 软件架构 通道 配置中心 配置管理 重构 错误与异常 问题汇总 阅读习惯
     
    推荐文章