awk命令

awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。

awk有3个不同版本: awk、nawk和gawk,未作特别说明,一般指gawk,gawk 是 AWK 的 GNU 版本。

awk其名称得自于它的创始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首个字母。实际上 AWK 的确拥有自己的语言: AWK 程序设计语言 , 三位创建者已将它正式定义为“样式扫描和处理语言”。它允许您创建简短的程序,这些程序读取输入文件、为数据排序、处理数据、对输入执行计算以及生成报表,还有无数其他的功能

代码块

awk的所有代码(目前这么认为)都是写在语句块中的。

语句块可分为3类:

BEGIN语句块、END语句块和main语句块。

其中BEGIN语句块和END语句块都是的格式分别为BEGIN{...}和END{...},而main语句块是一种统称,它的pattern部分没有固定格式,也可以省略,main代码块是在读取文件的每一行的时候都执行的代码块。

BEGIN代码块:

在读取文件之前执行,且执行一次
在BEGIN代码块中,无法使用$0或其它一些特殊变量
main代码块:

读取文件时循环执行,(默认情况)每读取一行,就执行一次main代码块
main代码块可有多个
END代码块:

在读取文件完成之后执行,且执行一次
有END代码块,必有要读取的数据(可以是标准输入)
END代码块中可以使用$0等一些特殊变量,只不过这些特殊变量保存的是最后一轮awk循环的数据

语法

awk [options] 'pattern{action}'   file1 fiel1

awk的语法:

多个pattern{action}可以直接连接连用
action中多个语句如果写在同一行,则需使用分号分隔
pattern部分用于筛选行,action表示在筛选通过后执行的操作
pattern和action都可以省略
省略pattern,等价于对每一行数据都执行action
例如:awk '{print $0}' a.txt
省略代码块{action},等价于{print}即输出所有行
例如:awk '/Alice/' a.txt等价于awk '/Alice/{print $0}' a.txt
省略代码块中的action,表示对筛选的行什么都不做
例如:awk '/Alice/{}' a.txt
pattern{action}任何一部分都可以省略
例如:awk '' a.txt

pattern{action}语句结构(都称之为语句块),其中的pattern部分可以使用下面列出的模式:

# 特殊pattern
BEGIN
END

# 布尔代码块
/regular expression/    # 正则匹配成功与否 /a.*ef/{action}
relational expression   # 即等值比较、大小比较 3>2{action}
pattern && pattern      # 逻辑与 3>2 && 3>1 {action}
pattern || pattern      # 逻辑或 3>2 || 3<1 {action}
! pattern               # 逻辑取反 !/a.*ef/{action}
(pattern)               # 改变优先级
pattern ? pattern : pattern  # 三目运算符决定的布尔值

# 范围pattern,非布尔代码块
pattern1, pattern2      # 范围,pat1打开、pat2关闭,即flip,flop模式

工作原理

# awk-F: {print $1,$3}' /etc/passwd

(1)awk使用一行作为输入,并将这一行赋给内部变量$0,每一行也可称为一一个记录,以换行符结束

(2)然后,行被: (默认为空格或制表符)分解成字段(或域),每个字段存储在已编号的变量中,从$1开始,最多达100个字段

(3)awk如何知道用空格来分隔字段的呢?因为有一个内部变量FS来确定字段分隔符。初始时,FS赋为空格

(4)awk打印字段时,将以设置的方法使用print西数打印,awk在打印的字段间加上空格,因为$1,$3之间有一个逗号。逗号比较特殊,它映射为另一个内部变量,称为输出字段分隔符OFS, OFS默认为空格

(5)awk输出之后,将从文件中获取另行,并将其存储在$0中,覆盖原来的内容,然后将新的字符串分隔成字段并进行处理。该过程将持续到所有行处理完毕

变量RS

可设置表示输入记录分隔符的预定义(Record Separator)来改变每次读取的记录模式。

RS通常设置在BEGIN代码块中,因为要先于读取文件就确定好RS分隔符。

RS指定输入记录分隔符时,所读取的记录中是不包含分隔符字符的。例如RS="a",则$0中一定不可能出现字符a

特殊的RS值用来解决特殊读取需求:

RS="":按段落读取
RS="\0":一次性读取所有数据,但有些特殊文件中包含了空字符\0
RS="^$":真正的一次性读取所有数据,因为非空文件不可能匹配成功
RS="\n+":按行读取,但忽略所有空行

RS两种可能情况:
·RS为单个字符:直接使用该字符来分割记录
·RS为多个字符:将其当做正则表达式,只要匹配正则表达式的符号,都用来分割记录
。设置预定义变量IGNORECASE为非索,正匹配时表示忽略大小写
。兼容模式下,只有首字符才生效,不会使用正则模式去分割记录

RT

在读取每条记录之后,将其赋值给$0,同时还会设置NR、FNR、RT。

在awk每次读完一条记录时,会设置一个称为RT的预定义变量,表示Record Termination。

当RS为单个字符时,RT的值和RS的值是相同的。

当RS为多个字符(正则表达式)时,则RT设置为正则匹配到记录分隔符之后,真正用于划分记录时的字符。

当无法匹配到记录分隔符时,RT设置为控制空字符串(即默认的初始值)。

NR

在读取每条记录之后,将其赋值给$0,同时还会设置NR、FNR、RT。

所有文件的行号计数器

FNR

在读取每条记录之后,将其赋值给$0,同时还会设置NR、FNR、RT。

是各个文件的行号计数器

字段分割

awk读取每一条记录之后,会将其赋值给$0,同时还会对这条记录按照预定义变量FS划分字段,将划分好的各个字段分别赋值给$1 $2 $3 $4...$N,同时将划分的字段数量赋值给预定义变量NF

$N引用字段:

N=0:即$0,引用记录本身
0<N<=NF:引用对应字段
N>NF:表示引用不存在的字段,返回空字符串
N<0:报错

方式:

读取record之后,将使用预定义变量FS、FIELDWIDTHS或FPAT中的一种来分割字段。分割完成之后,再进入main代码段(所以,在main中设置FS对本次已经读取的record是没有影响的,但会影响下次读取)。

FS或-F

FS或者-F:字段分隔符

FS为单个字符时,该字符即为字段分隔符
FS为多个字符时,则采用正则表达式模式作为字段分隔符
特殊的,也是FS默认的情况,FS为单个空格时,将以连续的空白(空格、制表符、换行符)作为字段分隔符
特殊的,FS为空字符串””时,将对每个字符都进行分隔,即每个字符都作为一个字段
设置预定义变量IGNORECASE为非零值,正则匹配时表示忽略大小写(只影响正则,所以FS为单字时无影响)
如果record中无法找到FS指定的分隔符(例如将FS设置为”\n”),则整个记录作为一个字段,即$1和$0相等。

FIELDWIDTHS

指定预定义变量FIELDWIDTHS按字符宽度分割字段,这是gawk提供的高级功能。在处理某字段缺失时非常好用。

·FIELDWIDTHS="3569"表示第一个字段3字符,第二字段5字符.…
·FIELDWIDTHS="81:562:33"表示:
。第一个字段读8个字符
。然后跳过1个字符再读5个字符作为第二个字段
。然后读6个字符作为第三个字段
。然后跳过2公字符在读33个字符作为第四个字段(如果不足33个字符,师读到结尾)
·FIELDWIDTHS="23*":
。第一个字段2个字符。第二个字段3个字符
。第三个字段剩余所有字符
。星号只能放在最后,且只能单独使用,表示剩余所有

FPAT

FS是指定字段分隔符,来取得除分隔符外的部分作为字段。

FPAT是取得匹配的字符部分作为字段。它是gawk提供的一个高级功能。

FPAT根据指定的正则来全局匹配record,然后将所有匹配成功的部分组成$1、$2...,不会修改$0。

awk 'BEGIN{FPAT="[0-9]+"}{print $3"-"}' a.txt
之后再设置FS或FPAT,该变量将失效

OFS

分割表示使用FS(field Separator),计算表示使用预定义变量OFS(Output Field Separator)。

修改$0,将使用FS重新分割字段,所以会影响$1、$2...
修改$1、$2,将根据$1到$NF等各字段来重新计算$0
即使是$1 = $1这样的原值不变的修改,也一样会重新计算$0
为不存在的字段赋值,将新增字段并按需使用空字符串填充中间的字段,并使用OFS重新计算$0
awk 'BEGIN{OFS="-"}{$(NF+2)=5;print $0}' a.txt
增加NF值,将使用空字符串新增字段,并使用OFS重新计算$0
awk 'BEGIN{OFS="-"}{NF+=3;print $0}' a.txt
减小NF值,将丢弃一定数量的尾部字段,并使用OFS重新计算$0
awk 'BEGIN{OFS="-"}{NF-=3;print $0}' a.txt

没有导致$0重建,$0就一直是原原本本的数据,所以指定OFS也无效。

当$0重建后,将自动使用OFS重建,所以即使没有指定OFS,它也会采用默认值(空格)进行重建。

如果重建$0之后,再去修改OFS,将对当前行无效,但对之后的行有效。所以如果也要对当前行生效,需要再次重建。

有FS、FIELDWIDTHS、FPAT三种获取字段的方式,可使用PROCINFO数组来确定本次使用何种方式获得字段。

PROCINFO是一个数组,记录了awk进程工作时的状态信息。

如果:

PROCINFO["FS"]=="FS",表示使用FS分割获取字段
PROCINFO["FPAT"]=="FPAT",表示使用FPAT匹配获取字段
PROCINFO["FIELDWIDTHS"]=="FIELDWIDTHS",表示使用FIELDWIDTHS分割获取字段

ARGV  数组,保存命令行本身这个字符串,如awk '(print 50)'  a.txt,这个命令中,ARGV[0]保存awk ARGV[1]保存a.txt:

ARGC  awk命令的参数的个数         FILENAME  awk命令所处理的文件的名称

ENVIRON:当前环境变量及其值的关联数组

自定义变量test :  awk -v test="test" 'begin{print test}'   awk   'begin{ test="test";print test}' 

-----------格式化输出printf

format格式的指示符都以开头,后跟一个字符:

%c:显示字符的ASCII码     %d, %i点十进制整数         %e,%E:科学计数法显示数值            %f:显示浮点数
%g,%G:以科学计数法的格式或浮点数的格式显示数值       %s:显示字符串    %u:无符号整数        %%显示%自身

修饰符
N:显示宽度                 -:  左对齐             +:显示数值符号

awk -F :'{printf "%-15s %i\n",$1,$3}'        /etc/passwd

--------------内置函数

length   返回string字符 キ中字符的个数

awk   -F : ‘{i1,while(i<NF){if(length)}}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凤舞飘伶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值