Awk 简介

简介


 Awk stands for the names of its authors “Aho, Weinberger, and Kernighan”


Awk也是一种编程语言, 他能让你格式化数据以及生成特定格式的报告.(翻译的好糙…)

总之, 你只需要记住它是用来格式化数据的就OK了.

Awk更像是一个过滤器, 它把读入的数据一行一行的过滤, 匹配你想要的内容, 如果匹配到了, 那就格式化输出, 匹配不到的就忽略.

Awk有一些特性:

  • 它把数据视为 '记录' 和 '字段'
  • 它也有变量, 条件和循环.
  • 它有数学操作符和字符串操作符
  • 它能生成格式化的报告
  • 它从标准输入读取数据, 把过滤之后的数据从标准输出打印出来, 不处理空文件.

基本语法:

  1. awk '/search pattern1/ {Actions} /search pattern2/ {Actions}' file

其中:

  • search pattern是要匹配的字符串
  • Actions是匹配到之后所进行的动作
  • 它能处理多个匹配和行为
  • file是值输入文件
  • 单引号的作用是防止里面的特殊字符被shell处理

Awk的工作方法

  • Awk每次从输入文件中读取一行.
  • 对于每一行, 如果匹配到了相应的内容, 就会执行相应的动作.
  • 如果匹配不到, 就什么也不做.
  • 在上面的语法中, 匹配项和动作有一即可.
  • 如果没有给出匹配项, Awk就会把每一行按照给定的动作执行
  • 如果动作没有给出, 默认是打印.
  • 如果大括号里面是空的, 那就什么也不干.(因为这样就代表给出了一个空的动作)
  • 在大括号里的每一个动作需要用分号(;)隔开.

然后我们开始举栗子:

先是有这样一个文件:

  1. cat awk.txt
  2. 100 Thomas Manager Sales $5,000
  3. 200 Jason Developer Technology $5,500
  4. 300 Sanjay Sysadmin Technology $7,000
  5. 400 Nisha Manager Marketing $9,500
  6. 500 Randy DBA Technology $6,000

打印每一行

  1. awk '{print;}' awk.txt
  2. 100 Thomas Manager Sales $5,000
  3. 200 Jason Developer Technology $5,500
  4. 300 Sanjay Sysadmin Technology $7,000
  5. 400 Nisha Manager Marketing $9,500
  6. 500 Randy DBA Technology $6,000

这里我们没有给出匹配项, 仅给出了动作,print打印.

打印匹配到的行

  1. awk '/Thomas/;/Nisha/' awk.txt
  2. 100 Thomas Manager Sales $5,000
  3. 400 Nisha Manager Marketing $9,500

这里跟原著有点不太一样, 原著是用回车把每一个要匹配的内容分开的, 但是这样不好修改, 看起来也怪怪的, 所以, 不如直接用分号把他们隔开啦~

上面的栗子打印了匹配到那两个名字的行(记录).

打印特定的字段(列)

这个例子打印了第2和第5个字段.

  1. awk '{print $2,$5}' awk.txt
  2. Thomas $5,000
  3. Jason $5,500
  4. Sanjay $7,000
  5. Nisha $9,500
  6. Randy $6,000

再看下面这个例子:

  1. awk '{print $3,$NF}' awk.txt
  2. Manager $5,000
  3. Developer $5,500
  4. Sysadmin $7,000
  5. Manager $9,500
  6. DBA $6,000

有点不一样了是吧? $NF的意思是最后一个字段.

每个字段都要用逗号(,)分开.

开始和结束

awk有一种特定的语法, 开始和结束.

  1. BEGIN { Actions}
  2. {ACTION} # 文件中的每一行默认的动作
  3. END { Actions }

有什么用呢? 正如表述所言, 开始定义了输出一开始的动作,而结束则定义了输出结束时的动作.

比如:

  1. awk 'BEGIN {print "Name\t Designation\tDepartment\tSalary";} {print $2,"\t",$3,"\t",$4,"\t",$NF;} END{print "Report Generated\n--------------";}' awk.txt
  2. Name Designation Department Salary
  3. Thomas Manager Sales $5,000
  4. Jason Developer Technology $5,500
  5. Sanjay Sysadmin Technology $7,000
  6. Nisha Manager Marketing $9,500
  7. Randy DBA Technology $6,000
  8. Report Generated
  9. --------------

如果太长了, 中间可以用回车隔开:

  1. $ awk 'BEGIN {print
  2. "Name\tDesignation\tDepartment\tSalary";}
  3. > {print $2,"\t",$3,"\t",$4,"\t",$NF;}
  4. > END{print "Report Generated\n--------------";
  5. > }' employee.txt
  6. Name Designation Department Salary
  7. Thomas Manager Sales $5,000
  8. Jason Developer Technology $5,500
  9. Sanjay Sysadmin Technology $7,000
  10. Nisha Manager Marketing $9,500
  11. Randy DBA Technology $6,000
  12. Report Generated
  13. --------------

条件语句

awk也有条件语句, 比如比较大小:

  1. awk '$1 >= 200' awk.txt
  2. 200 Jason Developer Technology $5,500
  3. 300 Sanjay Sysadmin Technology $7,000
  4. 400 Nisha Manager Marketing $9,500
  5. 500 Randy DBA Technology $6,000

上面的例子是打印第一个字段大于等于200的行.

再看下面这个例子, 是对字符串进行比较的:

  1. awk '$4 ~ /Tech/' awk.txt
  2. 200 Jason Developer Technology $5,500
  3. 300 Sanjay Sysadmin Technology $7,000
  4. 500 Randy DBA Technology $6,000

有点像[[ ]]里面的正则匹配, 好像就是正则匹配…

  1. awk '$4 ~ /[tT][abcde]/' awk.txt
  2. 200 Jason Developer Technology $5,500
  3. 300 Sanjay Sysadmin Technology $7,000
  4. 500 Randy DBA Technology $6,000

有点意思了,是吧!

计数!

awk既然是一种编程语言, 那基本的计数也是应该的:

  1. awk 'BEGIN { count=0;} $4 ~ /Tech/ { count++; } END { print "Number of employees in Technology Dept=",count;}' awk.txt
  2. Number of employees in Technology Dept= 3
  1. awk 'BEGIN { count=0;}
  2. > $4 ~ /Tech/ { count++; }
  3. > END { print "Number of employees in Technology Dept=",count;}' awk.txt
  4. Number of employees in Technology Dept= 3

附言

awk作为一门编程语言, 这点介绍仅仅是皮毛而已, 就像, 虽然你学了点C语言,能输出个12345了, 可C能做的可不是这么简单. :)

(我也只是学了点皮毛…)

扩展阅读

(这些扩展阅读也都是原作者自己写的, 很厉害的一个家伙!