3

awk 从入门到入土

 1 year ago
source link: https://dingfen.github.io/miscellaneous/2022/07/19/awk.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

awk 从入门到入土Permalink

何为 awk ?Permalink

awk 是一种用于文本处理、数据提取分析和报告常用的 linux 工具(命令)。与 sed 和 grep 一样,在日常编程和使用 linux 操作系统中,它是提升效率的法宝。

awk 处理的数据可以来自标准输入(stdin)、文件,或其它命令的输出。它支持用户自定义函数和动态正则表达式等功能,是linux/unix下的一个强大编程工具。它在命令行中使用,但更多是作为脚本来使用。awk 内有完备的“语言”,可以写出数组、函数、分支等复杂结构,且语法与 C 语言的相通之处。相比 sed grep 命令,灵活性是 awk 最大的优势,但其包含了复杂语法、正则表达式、内置变量(函数)也让很多人望而生畏。

另外,该工具之所以叫 AWK 是因为其取了三位创始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的 Family Name 的首字符。

awk 到底能做什么?Permalink

awk 功能强大,特点繁杂,若开篇介绍用法会让该博文显得杂乱无章,让人毫无阅读兴趣。我尝试抛开复杂的语法和命令格式,先利用几个例子让读者了解一下 awk 的工作方式和功能是怎样的。相信你一定会被 awk 强大的信息提取能力所折服。当你熟练掌握 awk 后,就再也不会烦恼于数据的格式化输出和信息提取了。

awk 对文件操作Permalink

  1. 逐行扫描文件。awk 的基本功能是搜索/匹配文件中包含特定模式的文本。当其中的内容匹配到了该模式时,awk 会在上执行指定的操作。awk 基本以行为处理单元,以这种方式一行一行地处理文本,直到遇到文件的末尾。

     例1:打印文件的每行的第一列(域)
     > awk '{print $1}' filename
    
     例2:打印文件的每一行
     > awk '{print $0}' filename
    

    print 是 awk 中最常用的操作,可打印出后面的字符,若有多个变量,用’,’连接。虽然脚本中只写了对一行的操作,但由于 awk 会以逐行的方式遍历整个文本,因此最终该命令会打印出每一行的结果。

  2. 将每一行输入拆分为字段。awk 逐行扫描文件后,再对行中的列(域)做匹配。可以使用 $n 来表示第n列的字符,而 $0 表示整一行。内置变量 $NF 表示字段总数,因此 $NF 可表示倒数第一列。对列的分割默认是空格,但也可以通过改变内置变量 FS 来改变分割符号。

     例3:从 /etc/passwd 文件中,按照":"分割打印出第2列和倒数第一列、倒数第二列:
     > awk -F":" '{print $2,$(NF),$(NF-1)}' /etc/passwd (或)
     > awk 'BEGIN{FS=":"} {print $2,$(NF),$(NF-1)}' /etc/passwd
    

    BEGIN 块表示该脚本块需要在 awk 逐行遍历文件前就执行,且只执行一次,通常用于初始化内部变量或计算数据。与之相反,END 块只能在awk 逐行遍历文件后执行,且执行一次

  3. 比较输入行/字段与模式。比较或匹配模式通常要涉及到正则表达式的相关知识,关于正则表达式可参考菜鸟教程。但 awk 还提供了类似 C 语言中的判断指令,从而做出更复杂的条件判断和算术逻辑。甚至可以完全抛弃文件,单独做一些复杂计算。

     例4:找到 test.txt 中最后一列大于 5000 的列并打印出来:
     > awk '{if ($NF > 5000) print $NF}' test.txt
    
     例5:使用 awk 命令计算 exp(5):
     > awk 'BEGIN {param = 5; result = exp(param); printf "Result is %f.\n", result}'
    

    awk 有大量的内置变量和内置函数,具体介绍在后小节。

  4. 对匹配的行执行动作。awk主要的操作就是print,将数据按规定的格式打印出来。但需要注意,awk 命令一般不直接修改文件,只能将输出信息重定向到某一个文件中(非源文件)。

awk.png

可用此图再回顾一下 awk 的四步流程。总结一下,awk 适用于数据文件转换和编制格式报告,并且能做到:1、格式化地输出信息。2、各种复杂的算术逻辑运算和字符串操作。3、配合逐行特性,实现条件和循环结构。

awk命令格式和选项Permalink

语法形式Permalink

使用 awk 命令时,一般遵循下面两种形式书写:

> awk [options] 'script' [var=value] [file(s) name]
> awk [options] -f scriptfile [var=value] [file(s) name]

接下来的几个小节开始介绍 awk 各个部分的使用规则:

常用命令选项 —— [options]Permalink

  • -F <fs> 或 –field-separator <fs> :fs 为指定输入分隔符,也可以是字符串或正则表达式。默认的分隔符是连续的空格或制表符
  • -v <var>=<value> 赋值一个用户定义变量,将外部变量传递给 awk
  • -f <scripfile> 从脚本文件中读取awk命令
  • -m[fr] <val]> 对 val 值设置内在限制,-mf选项限制分配给val的最大块数目;-mr选项限制记录的最大数目。这两个功能是Bell实验室版awk的扩展功能,在标准awk中不适用。

awk模式和操作 —— ‘script’Permalink

首先回顾一下前文所说:

awk 的基本功能是搜索/匹配文件中包含特定模式的文本。当其中的内容匹配到了该模式时,awk 会在上执行指定的操作。awk 基本以行为处理单元,以这种方式一行一行地处理文本,直到遇到文件的末尾。

模式操作无疑是 awk 命令中最重要的部分,而它们都会在 ‘script’ 处集中表达,其中

模式Permalink

模式可以是以下任意一个:

  • 正则表达式:使用通配符的扩展集。

    例6:从 employee.txt 文件中找到含有 manager 的行并打印
    > awk '/manager/ {print}' employee.txt 
    

    ‘/manager/’ 即要匹配字符串中含有 manager 的子串。找到后打印文件所在行,{print} 默认打印一行的所有列。

  • 关系表达式:使用运算符进行操作,可以是字符串或数字的比较测试。

    例7:打印 log.txt 中第一列大于2并且第二列等于 'Are' 的行的前三列:
    > awk '$1>2 && $2=="Are" {print $1,$2,$3}' log.txt
    

    $1>2 && $2==”Are” 表示第一列大于2且第二列为 ‘Are’,可以仅写一个条件,也可以完整地写出 if 语句结构,见下例。

  • 模式匹配表达式:用运算符~(匹配)和!~(不匹配)。

    例8:打印 test.txt 文件中第二列,并匹配以80开头并以80结束的行:
    > awk '{if ($2 ~ /^80$/) print}' test.txt
    
  • BEGIN 语句块、pattern 语句块、END 语句块。

    例9:找到 test.txt 文件中最长行的所占的字符数
    > awk 'BEGIN{max=0} {if (length($0) > max) max=length($0)} END{print max}' test.txt
    

    由三个语句块组成的模式甚至可看成一个简单 C 程序。length() 是 awk 的内置函数。更多函数可见菜鸟教程的整理

由于 awk 的逐行处理文本的特性,很多重要的全局信息往往通过内置变量表达,书写 awk 需要快速查表并使用:

内置变量 含义
NF 字段个数,(读取的列数)
NR 记录数(行号),从1开始,新的文件延续上面的计数,新文件不从1开始
FNR 读取文件的记录数(行号),从1开始,新的文件重新从1开始计数
FS 输入字段分隔符,默认是空格
OFS 输出字段分隔符 默认也是空格
RS 输入行分隔符,默认为换行符
ORS 输出行分隔符,默认为换行符
FILENAME 输入的文件名
例10:读出 /etc/passwd 文件的第三和第四列,并用等号连接。
> awk -F':' 'BEGIN{OFS="=";} {print $3,$4;}' /etc/passwd

操作Permalink

操作由一个或多个命令、函数、表达式组成,之间由换行符或分号隔开,并位于大括号内,主要部分是:

变量或数组赋值 输出命令 内置函数 控制流语句

awk 的变量赋值 —— [var=value]Permalink


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK