文本处理工具 awk - 每天进步一点点

本文介绍了AWK这一强大的文本分析工具的基本概念与使用方法。包括如何打印指定域、指定分隔符、使用内部变量NF获取列数、打印固定域、截取字符串等内容,并通过实例演示了如何使用AWK进行文本处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

awk介绍:

AWK是一种处理文本文件的语言,是一个强大的文本分析工具。之所以叫AWK是因为其取了三位创始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的Family Name的首字符。

不同于sed以行为单位,awk是基于列的文本处理工具,它的工作方式是按行读取文本并视为一条记录,每条记录以字段分割成若干字段,然后输出各字段的值。

awk认为文件都是结构化的,也就是说都是由单词和各种空白字符组成的,这里的“空白字符” 包括、Tab,以及连续的空格和Tab等。每个非空白的部分叫做“域”,从左到右一次是第一个域,第二个域,等等。

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


awk语法:

1
2
3
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文件,以此文件为例

1
2
3
4
5
[root@kurol ~]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这两个域:

1
2
3
4
5
[root@kurol ~]awk '{print $1,$4}' awk.txt 
john.wang 021-11111111
lucy.yang 021-22222222
jack.chen 021-33333333
lily.gong 021-44444444


打印全部内容:

1
2
3
4
5
[root@kurol ~]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”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@kurol ~]awk -F'{print $1}' awk.txt 
john
lucy
jack
lily
[root@kurol ~]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
[root@kurol ~]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可以简单地做到这点。当然,如果指定了不同的分隔符,结果可能不一样。


使用默认分隔符:

1
2
3
4
5
6
7
8
9
10
[root@kurol ~]awk '{print NF}' awk.txt 
4
4
4
5
[root@kurol ~]awk -F'{print NF}' awk.txt 
2
2
2
2


4、打印固定域

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


打印最后一列:

1
2
3
4
5
[root@kurol ~]awk '{print $NF}' awk.txt 
021-11111111
021-22222222
021-33333333
ShangHai


打印倒数第二列:

1
2
3
4
5
[root@kurol ~]awk '{print $(NF-1)}' awk.txt 
30
25
35
021-44444444


5、截取字符串

    可以使用substr()函数对指定域截取字符串。

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

输出awk.txt文件第一个域的第六个字符到最后一个字符的内容:

1
2
3
4
5
[root@kurol ~]cat awk.txt | awk '{print substr($1,6)}'    #
wang
yang
chen
gong


6、确定字符串的长度

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

1
2
3
4
5
6
7
8
9
10
11
[root@kurol ~]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
[root@kurol ~]cat awk.txt | awk '{print length}'
30
33
30
42


7、使用awk求列和

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

假设awk.txt的第三个域是年龄字段,对所有人的年龄进行计算:

1
2
3
4
[root@kurol ~]# cat awk.txt | awk 'BEGIN{total=0}{total+=$3}END{print total}'
110
[root@kurol ~]# cat awk.txt | awk 'BEGIN{total=0}{total+=$3}END{print total/NR}'
27.5


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值