前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Linux之awk命令详解(一)

Linux之awk命令详解(一)

作者头像
AsiaYe
发布2019-11-06 16:50:08
9.4K0
发布2019-11-06 16:50:08
举报
文章被收录于专栏:DBA随笔
Linux之awk命令详解 今天来讲讲awk命令的使用方法吧。一直以来,对于这个命令我都怀有一种崇敬之情,如果一个人在我面前敲下awk三个字母,我一定会觉得他是Linux界的精英。因为这个命令实在是太强大了,强大到我根本不知道它有多强大,今天终于鼓起勇气来学习这个命令了,希望笔记能写的清楚一点,好让大家都对这个命令有一定的了解。话不多说,开始搞。

awk是一个报告生成器,拥有强大的文本格式化能力。它的命名方式也是由三位大佬,分别叫Aho,Weinberger,Kernighan,的三个人,awk命令取得他们的名字首字母。

awk命令和sed命令以及grep命令被人们成为linux命令中的三剑客,grep适合单纯的查找或者匹配查找结果,set适合编辑匹配到的文本,而awk命令更适合格式化文本,对文本进行较为复杂的格式处理。

awk基本语法:

awk [option] 'pattern{action}' file1,file2,...filen

其中action中最常用的print命令。

01

一个简单入门

好了,开始我们的操作,看下图:

代码语言:javascript
复制
[root@dev01 yeyz_shell]# cat awk_test.txt 
this is a test file 
this is a test file 
this is a test file 
this is a test file 
this is a test file 
[root@dev01 yeyz_shell]# cat awk_test.txt | awk '{print $1,$2}'
this is
this is
this is
this is
this is

其中 awk '{print $1,$2}'是指打印出这个文件的第一列和第二列。当我们不指定分隔符的时候,awk会默认按照空格来进行分割,当字符中间的空格有多个的时候,awk会将连续的空格理解为一个分隔符。

当我们使用awk '{print $0}'的时候,会将这一列的值全部打印出来。如果需要拼接字符串的话,只需要在print的后面添加你想要拼接的字符串即可,如下:

代码语言:javascript
复制
[root@dev01 yeyz_shell]# cat awk_test.txt | awk '{print $1,$2,$3,"dog"}'
this is a dog
this is a dog
this is a dog
this is a dog
this is a dog

这里需要注意的是,$1和$2的两边不能加引号。

02

如何在收尾添加相关字符

首先我们再次给出awk的使用方法:

awk [option] 'pattern{action}' file1,file2,...filen

上面的例子说明了当action为print的时候,我们的测试结果,那么关于pattert,我们可以做如下测试。

如果我们想在awk的前后添加相关的声明信息,可以通过下面的方式:

代码语言:javascript
复制
[root@dev01 yeyz_shell]# cat awk_test.txt | awk 'begin{print "this is awk result:"} {print $1,$2,$3,"dog"} end{print "awk end"}'
this is a dog
this is a dog
this is a dog
this is a dog
this is a dog
[root@dev01 yeyz_shell]# cat awk_test.txt | awk 'BEGIN{print "this is awk result:"} {print $1,$2,$3,"dog"} END{print "awk end"}'
this is awk result:
this is a dog
this is a dog
this is a dog
this is a dog
this is a dog
awk end

可以看到,当我们把pattern的模式设置问BEGIN或者END的时候,它就可以在我们输出文件的时候,添加文件的首尾字符串,需要注意的是,BEGIN和END不能写为begin或者end。

03

分隔符

再次给出awk的基本语法:

awk [option] 'pattern{action}' file1,file2,...filen

上面两个例子,分别给出了awk命令关于例子1中的分隔符,我们在这个例子中详细说说,话不多说,看例子:

代码语言:javascript
复制
[root@dev01 yeyz_shell]# cat awk_test.txt 
this#is#a#test##file 
this#is#a#test##file 
this#is#a#test##file 
this#is#a#test##file 
[root@dev01 yeyz_shell]# cat awk_test.txt | awk -F# '{print $1,$2}' 
this is
this is
this is
this is

可以看到,当我们使用awk -F#的时候,awk命令就是用#作为分割符号,来分割这个文件中的内容了。

04

内置变量和自定义变量

上面三个例子分别从option、pattern以及action三个方面对awk命令进行了一些介绍,接下来我们看看awk命令当中的有些内置变量,常用的内置变量有:

NR 行号,当前处理文本行的行号

NF 当前行的字段的个数

FNR 个文件分别计数的行号

FILENAME 文件名称

FS 输入字段分隔符

OFS 输出字段分隔符

ARGC以及ARGV 数组以及命令行参数的个数

下面分别对这些变量进行举例说明:

FS 和 OFS 输入输出字段分隔符

FS的作用:

代码语言:javascript
复制
[root@dev01 yeyz_shell]# cat awk_test.txt 
this#is#a#test##file 
this#is#a#test##file 
this#is#a#test##file 
this#is#a#test##file 
[root@dev01 yeyz_shell]# cat awk_test.txt | awk -v FS='#' '{print $2,$3}'
is a
is a
is a
is a

FS使用#作为分隔符,对于输入的字符串进行处理

下面的例子是OFS使用-作为分隔符,输出文件中的内容:

代码语言:javascript
复制
[root@dev01 yeyz_shell]# cat awk_test2.txt 
this is a shell program
this is a shell program
this is a shell program
this is a shell program
[root@dev01 yeyz_shell]# cat awk_test2.txt | awk -v OFS='-' '{print $2,$3,$4}'
is-a-shell
is-a-shell
is-a-shell
is-a-shell

NR和NF 行数和每一行的列数

测试样例如下:

代码语言:javascript
复制
[root@dev01 yeyz_shell]# cat awk_test3.txt 
this is a test program
this is a shell test program
[root@dev01 yeyz_shell]# cat awk_test3.txt | awk '{print NR,NF}'
 
 

结果显示,第一行有五个单词,第二行有六个单词

FNR和NR的区别

代码语言:javascript
复制
[root@dev01 yeyz_shell]# cat awk_test3.txt 
this is a test program
this is a shell test program
[root@dev01 yeyz_shell]# cat awk_test4.txt 
this#is#a#test#program
this#is#a#shell#test#program
[root@dev01 yeyz_shell]# awk {'print NR,$0'} awk_test3.txt awk_test4.txt 
 this is a test program
 this is a shell test program
 this#is#a#test#program
 this#is#a#shell#test#program
[root@dev01 yeyz_shell]# awk {'print FNR,$0'} awk_test3.txt awk_test4.txt 
 this is a test program
 this is a shell test program
 this#is#a#test#program
 this#is#a#shell#test#program

从测试可知,FNR是把不同文件的行号进行了区分,而NR没有对文件的行号进行区分。

FILENAME 显示文件名称

代码语言:javascript
复制
[root@dev01 yeyz_shell]# awk {'print FILENAME,FNR,$0'} awk_test3.txt awk_test4.txt 
awk_test3.txt  this is a test program
awk_test3.txt  this is a shell test program
awk_test4.txt  this#is#a#test#program
awk_test4.txt  this#is#a#shell#test#program

这个还是比较好理解的。

ARGC和ARGV

其中ARGV是一个数组,数组包含下标,使用下标可以访问数组中的文件名称,如下:

代码语言:javascript
复制
[root@dev01 yeyz_shell]# awk 'BEGIN{print "aaa",ARGV[1]}' test1 test2
aaa test1

[root@dev01 yeyz_shell]# awk 'BEGIN{print "aaa",ARGV[2]}' test1 test2
aaa test2

[root@dev01 yeyz_shell]# awk 'BEGIN{print "aaa",ARGV[0],ARGV[1],ARGV[2]}' test1 test2
aaa awk test1 test2

[root@dev01 yeyz_shell]# awk 'BEGIN{print "aaa",ARGV[0],ARGV[1],ARGV[2],ARGC}' test1 test2
aaa awk test1 test2 

需要注意的是,ARGV[0]指的是awk这个命令,这一点是awk命令规定的,其他的参数都是值得是后面处理的文件的名称,ARGC指的是ARGV数组的值的个数,在本例子中,它的值是3。

自定义变量

以上就是awk的内置变量,如果我们要自定义自己想要的变量,可以通过下面的方式来进行定义:

代码语言:javascript
复制
[root@dev01 yeyz_shell]# awk -v var='yeyz' 'BEGIN{print var}'
yeyz
[root@dev01 yeyz_shell]# awk  'BEGIN{ var2="yyy" ; print var2}'
yyy

当变量写在{}外面的时候,需要使用-v参数,当变量写在{}里面的时候,不需要写-v参数,但是需要注意的是,二者都需要写上BEGIN这个模式。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-03-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DBA随笔 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档