欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

awk入门指南

程序员文章站 2022-06-24 21:56:15
...

1.AWK是一种处理文本文件的语言,是一个强大的文本分析工具。之所以叫AWK是因为其取了三位创始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的Family Name的首字符。
2.不同于sed以行为单位,awk是基于列的文本处理工具,它的工作方式是按行读取文本并视为一条记录,每条记录以字段分割成若干字段,然后输出各字段的值。
3.awk认为文件都是结构化的,也就是说都是由单词和各种空白字符组成的,这里的“空白字符” 包括、Tab,以及连续的空格和Tab等。每个非空白的部分叫做“域”,从左到右一次是第一个域,第二个域,等等。

$1、$2分别用于表示域,$0则表示全部域。

awk语法:

awk [选项参数] 'script' var=value file(s)
或者
awk [选项参数] -f scriptfile var=value file(s)
参数 作用
-F fs or --field-separator fs 指定输入文件折分隔符,fs是一个字符串或者是一个正则表达式,如-F:
-v var=value or --asign var=value 赋值一个用户定义变量
-f scripfile or --file scriptfile 从脚本文件中读取awk命令
-mf nnn and -mr nnn 对nnn值设置内在限制,-mf选项限制分配给nnn的最大块数目;-mr选项限制记录的最大数目。这两个功能是Bell实验室版awk的扩展功能,在标准awk中不适用
-W compact or --compat, -W traditional or --traditional 在兼容模式下运行awk。所以gawk的行为和标准的awk完全一样,所有的awk扩展都被忽略
-W copyleft or --copyleft, -W copyright or --copyright 打印简短的版权信息
-W help or --help, -W usage or --usage 打印全部awk选项和每个选项的简短说明
-W lint or --lint 打印不能向传统unix平台移植的结构的警告
-W lint-old or --lint-old 打印关于不能向传统unix平台移植的结构的警告
-W posix 打开兼容模式。但有以下限制,不识别:/x、函数关键字、func、换码序列以及当fs是一个空格时,将新行作为一个域分隔符;操作符=不能代替=;fflush无效
-W re-interval or --re-inerval 允许间隔正则表达式的使用,参考(grep中的Posix字符类),如括号表达式[[:alpha:]]
-W source program-text or --source program-text 使用program-text作为源代码,可与-f命令混用
-W version or --version 打印bug报告信息的版本

awk常用的方法:

创建一个awk.txt文件,以此文件为例

[[email protected] ~]# cat awk.txt 
john.wang  Male   30 021-11111111
lucy.yang  Female 25 021-22222222
jack.chen  Male   35 021-33333333
lily.gong  Female 20 021-44444444  ShangHai

1、打印指定域

既然awk使用$1、$2代表不同的域,则可以打印指定的域。拿awk.txt的第一行来说,第一个域为join.wang,第二个域为Male,第三个域为30、第四个域为021-11111111

打印$1、$4这两个域:
[[email protected] ~]# awk '{print $1,$4}' awk.txt 
john.wang 021-11111111
lucy.yang 021-22222222
jack.chen 021-33333333
lily.gong 021-44444444
打印全部内容:
[[email protected] ~]# awk '{print $0}' awk.txt     
john.wang  Male   30 021-11111111
lucy.yang  Female 25 021-22222222
jack.chen  Male   35 021-33333333
lily.gong  Female 20 021-44444444  ShangHai

2、指定打印分隔符

默认情况下awk是使用空白字符作为分隔符的,但是也可以通过-F参数指定分隔符,来区分不同的域(有点像cut命令)。

指定 “.” 作为分隔符,这样每一行的$1就是 "." 之前的字符,$2就是 "."之后的字符
比如第一行的$1是“join”,$2是“Male    30    021-11111111”
[[email protected] ~]# awk -F. '{print $1}' awk.txt 
john
lucy
jack
lily
[[email protected] ~]# awk -F. '{print $2}' awk.txt  
wang  Male        30 021-11111111
yang  Female 25 021-22222222
chen  Male   35 021-33333333
gong  Female 20 021-44444444  ShangHai
[[email protected] ~]# awk -F. '{print $1,$2}' awk.txt  
john wang  Male   30 021-11111111
lucy yang  Female 25 021-22222222
jack chen  Male   35 021-33333333
lily gong  Female 20 021-44444444  ShangHai

3、内部变量NF

文件awk.txt所包含的内容不多,所以很容易的知道它的前3行中每行都有4个域,最后一行是5个域。但是如果有时候文件很大,每行列数都不一样,考观察就不现实了,必须通过特定的方式来获得文件的列数。通过awk的内部变量NF可以简单地做到这点。当然,如果指定了不同的分隔符,结果可能不一样

使用默认分隔符:
[[email protected] ~]# awk '{print NF}' awk.txt 
4
4
4
5
[[email protected] ~]# awk -F. '{print NF}' awk.txt  
2
2
2
2

4、打印固定域

通过内部变量可以简单地得到每行的列数,而如果在NF之前加上$符号,则代表“最后一列”,这样不管每行有多少列,只要使用$NF就能打印出最后一列

打印最后一列:
[[email protected] ~]# awk '{print $NF}' awk.txt     
021-11111111
021-22222222
021-33333333
ShangHai
打印倒数第二列:
[[email protected] ~]# awk '{print $(NF-1)}' awk.txt 
30
25
35
021-44444444

5、截取字符串

可以使用substr()函数对指定域截取字符串。substr(指定域,第一个开始字符的位置,第二个结束的位置)其中第二个结束的位置可以为空,这样默认输出到该域的最后一个字符

输出awk.txt文件第一个域的第六个字符到最后一个字符的内容:
[[email protected] ~]# cat awk.txt |awk '{print substr($1,6)}'
wang
yang
chen
gong

6、确定字符串的长度

使用内部函数length可以确定字符串的长度。

[[email protected] ~]# cat awk.txt |awk '{print $0}'
john.wang  Male   30 021-11111111
lucy.yang  Female 25 021-22222222
jack.chen  Male   35 021-33333333
lily.gong  Female 20 021-44444444  ShangHai
[[email protected] ~]# cat awk.txt |awk '{print length}'        
33
33
33
43

7、使用awk求列和

结构化的数据在系统中是随处可见的,比如用ls -l命令得到的输出、各类系统的日志等。在日常工作中,经常有将其中的数据进行相加的需求。

假设awk.txt的第三个域是年龄字段,对所有人的年龄进行计算:
[[email protected] ~]# cat awk.txt |awk 'BEGIN{total=0}{total+=$3}END{print total}'
110
[[email protected] ~]# cat awk.txt |awk 'BEGIN{total=0}{total+=$3}END{print total/NR}'
27.5