awk入门教程

awk

awk 不仅是一个数据处理工具,而且是一门解释性的编程语言。它提供了十分强大的功能:支持流程控制、数学运算符,内置函数等。但是大多数时候 awk 只表现为一个命令,我们可以使用这个命令对文本数据进行格式化处理。

任务众多可以使用 awk 完成。以下只是其中的几个:

  • 文本处理
  • 产生格式化文本报告
  • 执行算术运算
  • 执行字符串操作等等

如果想深入学习 awk,可以到 官网 学习,如果只是简单学会使用,读完这篇文章即可。


一、基本用法

awk 的用法基本是下面的形式:

# 格式
$ awk [选项] '[条件] {动作}' 文件名

# 示例1
$ awk '/usr/ {print $0}' demo.txt
# 示例2 awk 使用选项 -F 指定分割符号为 ":",不指定分割符默认为 空格
$ awk -F : '/usr/ {print $0}' demo.txt 

对于 awk '/usr/ {print $0}' demo.txt ,它类似 shellwhile 循环:

$ while read line;do echo "$line";done <demo.txt

awk 后面接两个单引号并加上大括号 {} 来设定想要对数据进行的处理动作。当然 awk 可以处理后续接的文件,也可以读取来自前个指令的标准输出。print命令前面是一个正则表达式,只输出包含usr的行。

awk 隐藏了读取每一行的 while 循环,它会自动读取每一行,其中的 {print $0} 对应于 Shellwhile 循环体 echo "$line" 部分。

实际上,awk 默认会根据 空格制表符,将每一行分成若干字段,依次用 $1$2$3 代表第一个字段、第二个字段、第三个字段等等。

$ echo 'this is a test' | awk '{print $0}'
this is a test
$ echo 'this is a test' | awk '{print $1}'
this
$ echo 'this is a test' | awk '{print $2}'
is
$ echo 'this is a test' | awk '{print $3}'
a

awk指定参数的两种方式
• 通过选项的方式指定(比如前面的 -F
• 通过内置变量来指定(比如 -F 对应的内置变量是 FS ),其实选项的方式,最终还是会被赋值给内置变量的。
比如,以下两句中的 -F :-v FS=':' 都是指定分隔符为 :

$ tail -n 10 /etc/passwd | awk -F: '{print $1}'
$ tail -n 10 /etc/passwd | awk -v FS=':' '{print $1}'

其中,一个是通过选项指定,用 -F : 指定分割符为 :,实际上是对 内置变量 FS 进行赋值(后面会讲到)

另外一个通过给内置变量赋值来指定,因为是在命令行里,所以要用 -v 来说明这是对内置变量赋值 (v variable ,变量),用 -v FS=':' 给内置变量 FS 赋值。如果是在代码块里(花括号里),或者用脚本方式写(其实脚本方式也是写在花括号里),就不用 -v 来指定 了。


二、awk 运行方式

1. 命令行方式

# 格式
$ awk [选项] '[条件] {动作}' 文件名

# 示例
$ awk '{print $0}' demo.txt

2. 管道方式

# 格式
$ cat [文件名] | awk [动作]

# 示例
$ cat demo.txt | awk '{print $3}'

注意:前面的命令不一定是 cat 命令,只需要是输出就行。比如 ls 命令


3. 脚本

创建 .awk 后缀的脚本,并添加 chmod +x [文件名] 可执行权限

# 示例
$ touch test.awk
$ chmod +x test.awk
$ vim test.awk

添加以下内容

#!/usr/bin/awk -f

# 使用BEGIN指定字符来设定"FS"内置变量,不能用"-F"来指定了
BEGIN { FS=":" }

# 这里可以写命令行方式引号内的语句,即正则+命名
{
    print $1
}

执行

$ ./test.awk
-> 111:222:333
111
-> 222:333
222
...

三、 内置变量

awk 内置了很多变量,比如我们前面举例的 $ + 数字 表示某个字段,除此之外还提供一些其他的变量。

为了方便演示,我们新建一个 demo.txt ,如下所示:

$ vim demo.txt
1.1 2 3 A B C
4.1 5 6 D E F
7.1 8 9 H I J

1. NF

NF 代表当前行有多少个字段,$NF 就代表最后一个字段

$ cat demo.txt|awk '{print NF "\t" $NF}'
6	C
6	F
6	J

上面代码中,我们使用了转义

同理,$(NF-1) 就代表倒数第二个字段

$ cat demo.txt| awk '{print NF-1 "\t" $(NF-1)}'
5	B
5	E
5	I

2. NR

变量 NR 表示当前处理的是第几行,即表示当前行的行号。

$ awk  -F ':' '{print NR ") " $1}' demo.txt
1) 1.1 2 3 A B C
2) 4.1 5 6 D E F
3) 7.1 8 9 H I J

3. FS

此变量表示输入的数据域之间的分隔符,其默认值是空格。 我们可以使用 -F 命令行选项改变它的默认值。

$ awk 'BEGIN {print "FS = " FS}'
FS =  

其他

  • awk的其他内置变量如下:

FILENAME:当前文件名。

RS:它表示(输入)记录分隔符以及它的默认值是换行。

FNR:它类似于 NR,但相对于当前文件。这是当 awk 工作在多个文件非常有用。 FNR 的值将重置使用新的

文件。

ORS:输出记录换行符。一般我们肯定会理所当然的认为,换行符肯定就是\n 。但事实上,我们可以通过

ORS 变量指定相应的换行符。

ARGC:命令行参数的个数。

ARGV:命令后参数的数组。可以逐个打印,比如 ARGV[0],默认 ARGV[0] 为 “awk” 。


四、函数

awk 内置了许多函数,可以直接使用。

  • 常用的内置函数如下:
toupper():用于将字符转为大写。
tolower():字符转为小写。
length():	返回字符串长度。
substr():	返回子字符串。
sin():		正弦。
cos():		余弦。
sqrt():		平方根。
rand():		随机数。返回一个随机数N,在0和1之间,使得0<= N <1。
int():		整数。这个函数截断数字为整数值。

示例如下:

$ awk  -F ':' '{print int($1)}' demo.txt
1
4
7

五、awk 的模式(条件)

为了方便演示,我们新增了一个 demo1.txt。

$ vim demo1.txt
/usr/root
mysql
/usr/daemon
/usr/bin
sys

前面我们说到 awk 的[基本用法](# 一、基本用法),如下所示:

# 格式
$ awk [选项] '[条件] {动作}' 文件名

条件(Pattern),即为 模式,就是花括号前面的那一串字符串,如示例中的 /usr/Pattern 由于有方括号(表示该参数可忽略)。

条件(Pattern)/模式 的两种类型

  • 数学及逻辑运算符,包括:<===>=!=&&!
  • 正则表达式匹配,只有两个:~ (正则匹配返回true)、!~(正则不匹配返回true)。

其实正则表达式的 ~!~ 这两个符号并不是必须的,当不使用这两个符号时,表示对整行进行匹配,否则可以对指定列进行 匹配,另外正则表达式必须写在两个斜杠里**(/这是正则表达式/ )**

# 示例
$ awk -F ':' '/usr/ {print $1}' demo1.txt
/usr/root
/usr/daemon
/usr/bin

上面代码中,print 命令前面是一个正则表达式,只输出包含 usr 的行。

# 示例1 
$ awk -F ':' 'NR % 2 == 0 {print $1}' demo1.txt
mysql
/usr/bin

上面代码中,print 命令前面是数学逻辑条件,只输出偶数行

# 示例2
$ awk -F ':' '$1 == "/usr/root" {print $1}' demo1.txt
/usr/root
# 示例3
$ awk -F ':' '$1 == "mysql" || $1 == "sys" {print $1}' demo1.txt
mysql
sys

上面的示例 2 和示例 3 输出第一个字段等于指定值的行。


六、Begin 和 End

前面提到过,其实 awk 花括号里的内容,相当于有一个隐藏的循环,不断的一行一行的处理并输出。
但是,如果花括号用 BEGINEND 这两种模式定义了,则不会循环,它有特殊含义。BEGIN 定义的模式,故名思义,只会 在循环开始的时候执行一次,而 END 自然就是循环结束后,再执行。
下面我们新建一个 demo2.txt

$ vim demo2.txt
1 张三 男 22 北京
2 李四 男 23 上海
3 王五 女 18 广州 
4 小红 女 19 桂林 
5 小安 女 20 杭州 
6 小达 男 26 深圳 

执行以下 awk 语句

$ awk -v OFS='|' 'BEGIN{print "序号","姓名","性别","年龄","地址","\n------------"} {print $1,$2,$3,$4,$5} END{print "-----------"}' demo2.txt

序号|姓名|性别|年龄|地址|
------------
1|张三||22|北京
2|李四||23|上海
3|王五||18|广州
4|小红||19|桂林
5|小安||20|杭州
6|小达||26|深圳
-----------

可以看到,BEGIN 部分输出在开头,而 END 部分输出在结尾

以上的代码相当于下面的代码👇:

# BEGIN
print "序号","姓名","性别","年龄","地址","\n------------"
# Action
while(!END){
    {print $1,$2,$3,$4,$5};
}
# END
print "-----------"

当然,BEGIN 还可以用来定义变量

$ awk 'BEGIN { FS=":" } {print $1}' demo2.txt
1 张三 男 22 北京
2 李四 男 23 上海
3 王五 女 18 广州 
4 小红 女 19 桂林 
5 小安 女 20 杭州 
6 小达 男 26 深圳

七、if / if else语句

前面我们输出过偶数行,是这么输出的,是在模式里添加条件的

$ awk -F ':' 'NR % 2 == 0 {print $1}' demo1.txt

现在我们知道了还有 if 语句,所以还可以这么写

$ awk -F ':' '{if(NR % 2 == 0) print $1}' demo1.txt

如果是多条语句

$ awk -F ':' '{if(NR%2==0){print $1;print $2}}' demo1.txt

八、for/while/do…while

for 循环

$ awk 'BEGIN{for(i=1;i<=6;i++){print i}}'

while 循环

$ awk 'BEGIN{i=0;while(i<5){print i;i++}}'

do while 循环

$ awk 'BEGIN{i=1;do{print i;i++}while(i<5)}'

九、continue/break

continue 跳过本次循环,继续下次循环

$ awk 'BEGIN{for(i=1;i<=6;i++){if(i==4)continue;print i}}'
1
2
3
5
6

break 跳出整个循环

$ awk 'BEGIN{for(i=1;i<=6;i++){if(i==4)break;print i}}'
1
2
3

十、 next 与 exit

除了 BGEINEND 模式,其他的花括号语句快,其实里面都有一个 “隐藏“ 的循环,因为awk 是逐行处理文本的。

nextexit,相当于是 这种隐藏循环的 continuebreak

我们使用 [六、Begin 和 End](#六、Begin 和 End) 创建的 demo2.txt,示例如下

$ awk '{print $1, $2, $3, $4}' demo2.txt
1 张三 男 22
2 李四 男 23
3 王五 女 18
4 小红 女 19
5 小安 女 20
6 小达 男 26

可以看到逐行输出了文本。

使用 next 跳过一行 “隐藏” 循环,然后继续循环。

$ awk '{if(NR==2){next}print $1, $2, $3, $4}' demo2.txt
1 张三 男 22
3 王五 女 18
4 小红 女 19
5 小安 女 20
6 小达 男 26

使用 exit 跳过 “隐藏” 循环,结束循环。

$ awk '{if(NR==2){exit}print $1, $2, $3, $4}' demo2.txt
1 张三 男 22

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值