awk命令来自三位创始人Alfred Aho、Peter Weinberger、Brian Kernighan的姓氏缩写,其功能是对文本和数据进行处理。使用awk命令可以让用户自定义函数或正则表达式,对文本内容进行高效管理,awk与sed、grep并称为Linux系统中的“文本三剑客”。

AWK和sed的区别

  • AWK更像是脚本语言;
  • AWK用于"比较规范"的文本处理,用于统计数量并输出指定:字段;
  • 使用sed将不规范的文本,处理为"比较规范"的文本。

语法格式: awk  参数  文件名

AWK脚本的流程控制

  • 输入数据前例程:BEGIN{ }
  • 主输入循环:{ }
  • 所有文件读取完成例程:END{ }

AWK字段

AWK的字段引用和分离

  • 记录和字段
  • 每行称作AWK的记录
  • 使用空格、制表符分隔开的单词称作字段
  • 可以自行设定分隔的字段
  • 字段的引用
  • awk中使用$1、$2 、... 、$n表示第几个字段,例如:
awk  '{print $1,$2,$3}'  filename
  • awk可以使用-F选项改变字段分隔符,例如:
awk  -F  ":"  '{print $1,$2,$3}'  filename
  • 分隔符可以使用正则表达式,例如:
cat  /boot/grubs/grub.cfg

备注:grub.cfg 文件包含了 GRUB 用来引导操作系统所需的所有配置和菜单项,其中包含内核版本信息,如下:AWK命令 – 对文本和数据进行处理的编程语言_sed

我们现在需要做的就是提取出图中标注的信息:

  • 打印grub.cfg文件中,以menu开头的整行内容
awk '/^menu/{print $0}' /boot/grub2/grub.cfg

AWK命令 – 对文本和数据进行处理的编程语言_sed_02

  • 打印grub.cfg文件中,以menu开头的行中的内核信息
awk -F "'" '/^menu/{print $2}' /boot/grub2/grub.cfg

AWK命令 – 对文本和数据进行处理的编程语言_sed_03

  • 打印grub.cfg文件中,以menu开头的行中的第2个字段,并在每行前添加行号
awk -F "'" '/^menu/{print x++,$2}' /boot/grub2/grub.cfg

AWK命令 – 对文本和数据进行处理的编程语言_sed_04


AWK的表达式

赋值操作符

  • = 是最常用的赋值操作符
  • var1="name"
  • var2="hello" "world
  • var3=$1
  • 其他赋值操作符
  • ++ -- += -= *= /= %= ^=
  • ++表示加1,--表示减1

算术操作符

  • + - * / % ^


系统变量

字段分隔符FS和OFS

  • FS(Field Separator )表示输入的字段分隔符,对于输入的文件已什么样的符号作为字符分隔符判断
  • OFS(Output Field Separator)表示输出的字段分隔符
  • 分隔符默认是空格或制表符

举例:

head -5 /etc/passw

AWK命令 – 对文本和数据进行处理的编程语言_sed_05


  1. 显示文件passwd的前5行内容,然后以“:”作为分隔符,筛选出其中每一行的第1个字段(即第1列)显示。
head -5 /etc/passwd | awk 'BEGIN{FS=":"}{print $1}'

如图所示:

AWK命令 – 对文本和数据进行处理的编程语言_sed_06


  1. 显示文件passwd的前5行内容,然后以“:”作为分隔符,筛选出其中每一行的第1个字段(即第1列)和第2个字段(即第2列)显示。
head -5 /etc/passwd | awk 'BEGIN{FS=":"}{print $1,$2}'

AWK命令 – 对文本和数据进行处理的编程语言_sed_07

备注:未指定分隔符的情况下,分隔符默认为空格或制表符


  1. 显示文件passwd的前5行内容,然后以“:”作为输入分隔符(FS),筛选出其中每一行的第1个字段(即第1列)和第2个字段(即第2列),再然后两个字段之间以“-”为输出分隔符(即OFS)显示。
head -5 /etc/passwd | awk 'BEGIN{FS=":";OFS="-"}{print $1,$2}'

AWK命令 – 对文本和数据进行处理的编程语言_sed_08


记录分隔符RS

  • RS(Record Separator)用于标记输入的行的分隔符(默认是换行符[\n]),一般在多行合并为单行处理时用到

举例:

  • 显示文件passwd的前5行内容,然后以冒号(:)为记录分隔符显示整行信息。
head -5 /etc/passwd | awk 'BEGIN{RS=":"}{print $0}'

AWK命令 – 对文本和数据进行处理的编程语言_sed_09

备注:以冒号(:)为记录分隔符,具体如何来理解?

表示在读到内容遇到冒号(:)时,会认为该行已结束,后面的内容是新的一行,如上图命令执行结果所示。


NR和FNR行数

  • NR(Number of Record)
  • FNR(File Number of Record )

两者均用于显示行号,区别在于同时显示多个文件,NR在显示行号时,会累加,不会重排,而FNR会根据每个文件,行号会重排。

举例:

  1. 显示文件passwd的前5行内容,然后显示这5行的行号(仅显示行号,不显示内容)。
head -5 /etc/passwd | awk '{print NR}'

AWK命令 – 对文本和数据进行处理的编程语言_sed_10

  1. 显示文件passwd的前5行内容,然后显示这5行的行号,同时显示每一行的整行内容,如下:
head -5 /etc/passwd | awk '{print NR,$0}'

AWK命令 – 对文本和数据进行处理的编程语言_sed_11

  1. 显示文件passwd的前5行内容,然后显示这5行的行号,同时显示每一行的整行内容,如下:
head -5 /etc/passwd | awk '{print FNR,$0}'

AWK命令 – 对文本和数据进行处理的编程语言_sed_12

    从第2/3例,可以看到,在显示单个文件时,NR和FNR功能完全相同

  1. 在显示多个文件时,如下
awk '{print NR,$0}' /etc/hosts /etc/hosts
awk '{print FNR,$0}' /etc/hosts /etc/hosts

AWK命令 – 对文本和数据进行处理的编程语言_sed_13

  1. 以“:”作为输入分隔符(FS),输出显示文件passwd内容中的第2行的第7个字段
awk -F ":" 'NR==2 {print $7}' /etc/passwd

AWK命令 – 对文本和数据进行处理的编程语言_sed_14

  1. 以“:”作为输入分隔符(FS),输出显示文件passwd内容中的第1行的第7个字段和第2行的第7个字段
awk -F ":" 'NR==1{print $7} NR==2{print $7}' /etc/passwd

AWK命令 – 对文本和数据进行处理的编程语言_sed_15



NF字段数量

  • NF(Number of Field)最后一个字段内容可以用$NF取出

举例:

  1. 显示文件passwd的前5行内容,然后将这些内容作为awk命令的输入,以冒号(:)作为字段分隔符,输出每一行的字段数
head -5 /etc/passwd | awk 'BEGIN{FS=":"}{print NF}'

AWK命令 – 对文本和数据进行处理的编程语言_sed_16

  1. 显示文件passwd的前5行内容,然后将这些内容作为awk命令的输入,以冒号(:)作为字段分隔符,输出每一行第$NF行(即$7)字段
head -5 /etc/passwd | awk 'BEGIN{FS=":"}{print $NF}'

AWK命令 – 对文本和数据进行处理的编程语言_sed_17


综合应用示例

cat -n password

AWK命令 – 对文本和数据进行处理的编程语言_sed_18

cat password | awk 'BEGIN{FS=":";RS="-"} NR==1{print $2}'

AWK命令 – 对文本和数据进行处理的编程语言_sed_19

命令解析:

cat命令查看文本文件passwd内容,然后通过awk命令筛选内容,

内容筛选分为两个步骤,

  • 第一个步骤:划分文本passwd的内容

通过命令的第一部分BEGIN{FS=":";RS="-"}来对内容进行划分,这一步骤执行后的结果为:

AWK命令 – 对文本和数据进行处理的编程语言_sed_20

  • 第二个步骤:筛选输出内容

通过命令中的NR1{print $2},首先通过NR1筛选出上图中的第一行内容root:x,然后通过$2,筛选出这一行的第2个字段x。


关系操作符

布尔操作符


AWK的条件语句和循环语句

条件语句

条件语句使用if开头,根据表达式的结果来判断执行哪一条语句

如下:

if (表达式)
  awk语句1
[else
  awk语句2
]

注:

  • 语句中表达式成功时,返回值为1;不成立时,返回值为0;
  • 如果有多个语句要执行,可以将awk语句的部分用{ }括起来,看例2;

举例:

样例文件kpi.txt,内容是5个员工名称及对应每个人半年内的kpi打分

cat  kpi.txt

AWK命令 – 对文本和数据进行处理的编程语言_sed_21

  1. 要求 输出第2个月份的kpi分值 大于等于80分的 员工名称
awk '{if($2>=80) print $1}' kpi.txt
#大括号{}中所有项之间可以完全不加空格

AWK命令 – 对文本和数据进行处理的编程语言_sed_22

  1. 要求 输出 第2个月份的kpi分值大于等于80分的 员工名称和kpi分值
awk '{if($2>=80) {print $1;print $2} }' kpi.txt

AWK命令 – 对文本和数据进行处理的编程语言_sed_23

注:

多条awk语句,如果不加大括号{ },会如何显示,如下:

awk '{if($2>=80) print $1;print $2}' kpi.txt

AWK命令 – 对文本和数据进行处理的编程语言_sed_24

这里就不详细讲了,自行测试下吧


循环语句

第一种:while循环

while(表达式)
  awk语句1

第二种:do循环

do{
  awk语句1
}while(表达式)

第三种:for循环

for(初始值;循环判断条件;累加)
  awk语句1

影响控制的其他语句

  • break
  • continue

举例:



  1. 33333333333
  2. 4444444444









没写完,会一点点优化更新