awk编程?let‘s go(一) ---- 初识awk

2022/1/29 11:04:33

本文主要是介绍awk编程?let‘s go(一) ---- 初识awk,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

目录

  • 前言
  • 快速开始
  • AWK 程序的结构
  • 运行 AWK 程序
  • AWK的简单的输出
      • 打印每一行
      • 打印某些字段
      • NF, 字段的数量
      • 打印行号
      • 将文本放入输出中
  • 更精美的输
      • 字段排列
      • BEGIN 与 END

温馨提示,本文适合有一定编程基础的人阅读。

前言

在学习本文之前,相信有一部分人和我之前一样,对awk的认知停留于对某个简单命令的使用。对于我们做 java 开发的,最经典的一个案例莫过于重启服务时经常看到的一个脚本

#!/bin/bash
# 重启xx服务

ps -ef | grep application | grep -v grep | awk '{print $2}' | xargs kill -9
# 重启服务
nohup java -jar xxx.jar ...

在上面的一个脚本中我们使用了awk命令,也可以看懂这个命令的作用,至于到底是什么原理或者说为什么有这样的效果很多人是不清楚。反正大家都是这么写的,我要做的只是 copy copy 改~。那么今天开始我们将一起学习awk,其实awk远比你认知的要更为强大!

快速开始

例如有以下一个文件 employ.dat,文件包含员工姓名、每小时的工资、工作时长,每一行代表一个员工的记录

张三       25.00      0
李四       22.75      0
王五       19.00     10
赵六       30.00     20
钱七       42.50     22
王八       80.00     18

现在想要打印每个员工的姓名以及工资(时薪 * 工作时长),而且雇员的工作时长(第三列)必须大于0,这时候只需要下面的一行命令即可以完成上面的工作:

awk '$3 > 0 {print $1 ,$2 * $3}'  employ.dat

执行上面的命令后结果如下:

王五 190
赵六 600
钱七 935
王八 1440

通过输出的结果可以看出上面的命令已经很好的完成了我们的需求。
该行命令告诉操作系统运行 awk 程序, 被运行的程序用单引号包围起来, 从输入文件 emp.data 获取数据。单引号包围的部分是一个完整的 awk 程序. 它由一个单独的 模式–动作 语句 (pattern-action statement) 组成. 模式 $3 > 0 扫描每一个输入行, 如果该行的第三列 (或者说 字段 (field)) 大于零, 则动作

{print $1 ,$2 * $3}

再来一个需求,打印出工作时长为0的员工姓名,相信有了上面的例子,完成这个需求也很简单:

awk '$3 == 0 {print $1}'  employ.dat

AWK 程序的结构

在上面的命令行中, 被单引号包围的部分是使用 awk 语言编写的程序,每一个 awk 程序都是由一个或多个 模式–动作 语句组成的序列:

pattern { action }
pattern { action }
...

awk 的基本操作是在由输入行组成的序列中, 陆续地扫描每一行, 搜索可以被模式 匹配 (match) 的行.。“匹配”的精确含义依赖于问题中的模式, 比如, 对于 $3 > 0, 意味着 “条件为真”.。每一个输入行轮流被每一个模式测试. 每匹配一个模式, 对应的动作 (可能包含多个步骤) 就会执行。 然后下一行被读取, 匹配重新开始. 这个过程会一起持续到所有的输入被读取完毕为止。

运行 AWK 程序

运行一个 awk 程序有多种方式. 可以键入下面这种形式的命令
awk 'program' input files
这个命令对指定的输入文件的每一行, 执行 program. 例如你可以键入
awk '$3 == 0 { print $1 }' file1 file2

AWK的简单的输出

打印每一行

如果一个动作没有模式, 对于每一个输入行, 该动作都会被执行. 语句 print 会打印每一个当前输入行,
所以程序
{ print }
会将它所有的输入打印到标准输出. 因为 $0 表示一整行, 所以程序
{ print $0 }
完成同样的工作

打印某些字段

这种方式前面我们已经使用到了,例如打印第一列和第三列可以使用
{print $1, $3}

NF, 字段的数量

Awk 计算当前输入行的字段数量, 并将它存储在
一个内建的变量中, 这个变量叫作 NF (Number Of Field)。因此程序
{ print NF, $1, $NF }
将会打印每一个输入行的字段数量, 第一个字段, 以及最后一个字段。

打印行号

Awk 提供了另一个内建变量 NR (Number Of Record), 这个变量计算到目前为止, 读取到的行的数量. 我们可以使用 NR 和 $0为 employ.dat 的每一行加上行号:
awk '{ print NR, $0 }' employ.dat
输出就像这样:

1 张三       25.00      0
2 李四       22.75      0
3 王五       19.00     10
4 赵六       30.00     20
5 钱七       42.50     22
6 王八       80.00     18

将文本放入输出中

可以把单词放在字段与算术表达式之间:
awk '{ print "第",NR, "行记录是", $0 }' employ.dat

第 1 行记录是 张三       25.00      0
第 2 行记录是 李四       22.75      0
第 3 行记录是 王五       19.00     10
第 4 行记录是 赵六       30.00     20
第 5 行记录是 钱七       42.50     22
第 6 行记录是 王八       80.00     18

更精美的输

print 用于简单快速的输出. 如果读者想要格式化输出, 那么就需要使用 printf 语句。

字段排列

printf语句具有形式
printf(format, value1, value2, ... , valuen)
format 是一个字符串, 它包含按字面打印的文本, 中间散布着格式说明符, 格式说明符用于说明如何打印值。一个格式说明符是一个 %, 后面跟着几个字符, 这些字符控制一个 value 的输出格式. 第一个格式说明符说明value1 的输出格式, 第二个格式说明符说明 value2 的输出格式, 依次类推. 于是, 格式说明符的数量应该和被打印的 value 一样多。
这个程序使用 printf 打印每位员工的工资:
awk '{ printf(" %s 的工资是 %.2f元\n", $1, $2 * $3) }' employ.dat

 张三 的工资是 0.00元
 李四 的工资是 0.00元
 王五 的工资是 190.00元
 赵六 的工资是 600.00元
 钱七 的工资是 935.00元
 王八 的工资是 1440.00元

BEGIN 与 END

特殊的模式 BEGIN 在第一个输入文件的第一行之前被匹配, END 在最后一个输入文件的最后一行被处理
之后匹配. 这个程序使用 BEGIN 打印一个标题:
awk 'BEGIN { print "姓名 时薪 工作时长"; print "" } { print }' employ.dat

姓名 时薪 工作时长

张三       25.00      0
李四       22.75      0
王五       19.00     10
赵六       30.00     20
钱七       42.50     22
王八       80.00     18

今天的内容就到这里了,欲知后事如何,请听下回分解。



这篇关于awk编程?let‘s go(一) ---- 初识awk的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程