linuxawk命令实用手册

编程

0,简介

Linux awk 是一个实用的文本处理工具,它不仅是一款工具软件,也是一门编程语言awk 的名称来源于其三位作者的姓氏缩写,其作者分别是Alfred AhoPeter WeinbergerBrian Kernighan

如果你在linux 系统中追踪awk,可以看到其最终指向的是/usr/bin/gawk,也就是gawk 命令。其GNU官方手册 权威且全面,但对于初学者并不是很友好,因为内容非常多,你可能不知从何看起。对于普通用户,一般也用不到非常复杂的功能。

如果一个文件由规则的多个列组成,则非常适合使用awk 来处理。本文介绍awk 常用方法,对于普通使用者应该是足够了。

1,基本概念

awk 命令会对文本文件每一行进行处理,其语法格式如下:

awk `参数` `pattern {action}` `filename`

pattern 是要匹配的规则,action 是要执行的动作,只有匹配了pattern,才会执行动作action

这句命令的含义是:对于文件filename 的每一行,如果能够符合条件pattern,则执行动作action。如果不写pattern,则表示对于文件filename的每一行,都进行action 处理。

1.1,参数

awk 最常使用的参数是-F,其后跟一个分隔符或者正则表达式,其表示的意思是以怎样的规则对每一行进行分割。 默认是空格Tab键

1.2,pattern

pattern 可以是下表中的任意一项:

pattern

说明

/正则表达式/

正则写在两个/ 之间

关系表达式

awk 中支持的关系运算符组成

模式匹配表达式

~(匹配)和!~(不匹配)组成

BEGIN{语句}

在处理第一行文本之前,执行BEGIN 块中的语句,可以在这里进行一些变量初始化等操作

END{语句}

在处理完最后一行文本之后,执行END 块中的语句

/规则1/,/规则2/

这是一个范围模板,只处理规则1第一次出现与规则2第一次出现之间的行

1.3,action

actionawk 语句组成,比如print,用于输出。

2,awk 内置变量

awk 中内置了很多变量,来方便使用,这里介绍一些常用的:

awk 内置变量

含义

FS

表示分隔符,类似-F 参数的功能

$0

一行的完整内容

$n

分隔符隔开的第n列,比如$1 表示第一列

FILENAME

当前文件名

NR

当前行数,即当前行是第几行

NF

当前行的列数,即当前行分割符分成了几列

IGNORECASE

如果为真,表示忽略大小写进行匹配

3,awk 内建函数

awk 常用函数如下:

函数

含义

tolower()

字符串转小写

toupper()

字符串转大写

length()

计算字符串长度

split()

字符串分割

systime()

Unix 时间戳

strftime()

时间格式化,用法同C语言中的strftime 函数

rand()

随机数

sin()

正弦

cos()

余弦

sqrt()

平方根

exp()

求幂

4,awk 运算符

awk 支持如下常用运算符

运算符

含义

+ - * / &

加,减,乘,除,求余

= += -= *= /= %= ^= **=

赋值运算符

< <= > >= != ==

比较运算符

空格

用于连接字符串,使用较多

`

&&

逻辑

!

逻辑

~

匹配

!~

不匹配

5,awk 使用案例

假如,我们有如下文件,分别为姓名性别年龄成绩等级省份

>>> cat log.txt 

_________________

小明,男,23,550^优秀---北京

小丽,女,22,560^优秀---河北

小磊,男,24,530^良好---河南

小召,男,23,540^优良---山东

小欣,女,23,545^优良---山西

5.1 使用-F

以逗号,分隔符,并将第1列,第2列和第3列输出,如下:

>>> awk -F, "{print $1,$2,$3}" log.txt 

______________________________________

小明 男 23

小丽 女 22

小磊 男 24

小召 男 23

小欣 女 23

分隔符只有一个字符时,分割符可以紧挨-F,还有如下几种写法:

awk -F , "{print $1,$2,$3}" log.txt		#`分隔符`与`-F`之间有一个空格

awk -F"," "{print $1,$2,$3}" log.txt #`分隔符`用单引号引住,并且紧挨`-F`

awk -F"," "{print $1,$2,$3}" log.txt #`分隔符`用双引号引住,并且紧挨`-F`

awk -F "," "{print $1,$2,$3}" log.txt #`分隔符`用单引号引住,与`-F`之间有空格

awk -F "," "{print $1,$2,$3}" log.txt #`分隔符`用双引号引住,与`-F`之间有空格

分隔符多个连续字符时,必须用双引号或者单引号引住分割符,可以紧挨-F,也可以有空格

awk -F "---" "{print $2}" log.txt	#`分隔符`用单引号引住,与`-F`之间有空格

awk -F"---" "{print $5}" log.txt #`分隔符`用双引号引住,与`-F`之间没有空格

以上两个命令输出的内容一样,此时分隔符---,每一行都被分成了两列,如下:

小明,男,23,550^优秀 北京

小丽,女,22,560^优秀 河北

小磊,男,24,530^良好 河南

小召,男,23,540^优良 山东

小欣,女,23,545^优良 山西

当有多个单独的分割符时,将多个分隔符写在中括号[]中,如下,表示以, 或者以--- 为分隔符:

>>> awk -F "[,^]" "{print $1, $2, $3, $4, $5}" log.txt 

________________________

小明 男 23 550 优秀---北京

小丽 女 22 560 优秀---河北

小磊 男 24 530 良好---河南

小召 男 23 540 优良---山东

小欣 女 23 545 优良---山西

5.2 使用内置变量

我们用变量NR输出当前行号,变量NF输出当前行的列数,变量FILENAME输出当前文件名,如下:

>>> awk -F"---" "{print NR, $1, $2, NF, FILENAME}" log.txt

__________________________________________________________

1 小明,男,23,550^优秀 北京 2 log.txt

2 小丽,女,22,560^优秀 河北 2 log.txt

3 小磊,男,24,530^良好 河南 2 log.txt

4 小召,男,23,540^优良 山东 2 log.txt

5 小欣,女,23,545^优良 山西 2 log.txt

5.3 如何连接字符串

我们将每一列使用竖线| 分割,方法是将分隔符双引号引住,然后紧挨变量,如下:

>>> awk -F"---" "{print NR"|"$1"|"$2"|"NF"|"FILENAME}" log.txt

__________________________________

1|小明,男,23,550^优秀|北京|2|log.txt

2|小丽,女,22,560^优秀|河北|2|log.txt

3|小磊,男,24,530^良好|河南|2|log.txt

4|小召,男,23,540^优良|山东|2|log.txt

5|小欣,女,23,545^优良|山西|2|log.txt

5.3 使用内置函数

使用内置函数systime() 输出时间戳,如下:

>>> awk -F"---" "{print NR"|"$1"|"$2"|"NF"|"FILENAME"|"systime()}" log.txt

—————————————————————————————————————————————

1|小明,男,23,550^优秀|北京|2|log.txt|1587022443

2|小丽,女,22,560^优秀|河北|2|log.txt|1587022443

3|小磊,男,24,530^良好|河南|2|log.txt|1587022443

4|小召,男,23,540^优良|山东|2|log.txt|1587022443

5|小欣,女,23,545^优良|山西|2|log.txt|1587022443

使用length 输出行长度大于5 的行:

>>> awk "length>5" log.txt

——————————————————————————

小明,男,23,550^优秀---北京

小丽,女,22,560^优秀---河北

小磊,男,24,530^良好---河南

小召,男,23,540^优良---山东

小欣,女,23,545^优良---山西

5.4 使用pattern

使用pattern 只输出 同学信息,$0 表示每一行的原始内容,如下:

>>> awk "/男/ {print NR"|"$0}" log.txt

__________________________

1|小明,男,23,550^优秀---北京

3|小磊,男,24,530^良好---河南

4|小召,男,23,540^优良---山东

5.5 使用逻辑非!

使用逻辑非!,输出不为的学生信息:

>>> awk "!/男/ {print NR"|"$0}" log.txt

__________________________

2|小丽,女,22,560^优秀---河北

5|小欣,女,23,545^优良---山西

5.6 使用关系表达式

使用关系表达式,输出年龄为23 的学生信息:

# 以逗号分割后的第三列为年龄

>>> awk -F, "$3==23 {print $3, $0}" log.txt

____________________________

23 小明,男,23,550^优秀---北京

23 小召,男,23,540^优良---山东

23 小欣,女,23,545^优良---山西

也可以写成如下方式,输出年龄为23或25 的学生信息:

>>> awk -F, "$3==23 || $3==25" log.txt

________________________

小明,男,23,550^优秀---北京

小召,男,23,540^优良---山东

小欣,女,23,545^优良---山西

5.7 使用模式匹配表达式

使用模式匹配表达式,输出年龄为24 的学生信息:

awk -F, "$3 ~/24/ {print $3, $0}" log.txt

24 小磊,男,24,530^良好---河南

5.8 使用if 语句

awk 也支持if 语句,输出年龄为22 的学生信息,if 语句写在大括号{}内:

>>> awk -F, "{if($3==22) print $3, $0}" log.txt

___________________________

22 小丽,女,22,560^优秀---河北

5.9 使用NR 输出基数行

# `NR % 2 == 1` 为基数行

>>> awk -F, "NR % 2 == 1 {print NR, $0}" log.txt

——————————————————————————

1 小明,男,23,550^优秀---北京

3 小磊,男,24,530^良好---河南

5 小欣,女,23,545^优良---山西

5.10 使用NF 输出倒数第一列

$(NF) 为倒数第1列,$(NF-1) 为倒数第2列,$(NF-2) 为倒数第3列,依次类推。

如下输出倒数第1列:

>>> awk -F, "{print $(NF)}" log.txt

______________

550^优秀---北京

560^优秀---河北

530^良好---河南

540^优良---山东

545^优良---山西

5.11 使用BEGIN 块

BEGIN 块中可以是任意多个合法的awk 语句

>>> awk -F, "BEGIN{print "姓名", "性别", "年龄"} {print $1, $2, $3}" log.txt 

____________

姓名 性别 年龄

小明 男 23

小丽 女 22

小磊 男 24

小召 男 23

小欣 女 23

5.12 使用END 块

END 块中可以是任意多个合法的awk 语句BEGIN 块END 块可以一起使用。

>>> awk -F, "BEGIN{print "姓名", "性别", "年龄"} {print $1, $2, $3} END{print "共有"NR"行信息"}" log.txt 

____________

姓名 性别 年龄

小明 男 23

小丽 女 22

小磊 男 24

小召 男 23

小欣 女 23

共有5行信息

5.13 使用范围模板

输出小丽和小欣之间的行数据:

>>> awk "/小丽/,/小欣/" log.txt 

______________________________

小丽,女,22,560^优秀---河北

小磊,男,24,530^良好---河南

小召,男,23,540^优良---山东

小欣,女,23,545^优良---山西

(完。)

以上是 linuxawk命令实用手册 的全部内容, 来源链接: utcz.com/z/515587.html

回到顶部