学会AWK,只看这一篇就够了

awk简介

1.awk是一种编程语言,用于Linux下对文本和数据进行处理。数据可以来自:标准输入,文件,其他命令的输出命令,使用管道符

2、awk是以它的三位发明者姓名的首字母命名的

3.awk是一个行级文本的高效处理工具

4.awk的最大优势就是很灵活

awk语法格式:

awk+[Option] +脚本命令+filename

或使用管道符 df -hT |awk 

常用option 以此命令为例

awk -F"\t" '{a[$2]+=$4}END{for(i in a) print i"\t"a[i]}'

-F 后面跟分隔符,以什么作为一行数据的分隔符,默认为空格,此例就是以\t作为分隔符

-f 后面指定脚本文件名,将脚本写入一个文件中,避免awk书写太长,使得不方便

-v 后面加变量

 

脚本命令:

awk的强大正是来源于它的脚本命令

脚本命令=匹配规则+执行命令

两者只可以有一个,但不可以一个没有,脚本命令必须用''括起来,当匹配规则为字符串和正则表达式的时候需要使用”/.../“符号括起来;而执行命令需要使用{}括起来,还有执行awk的时候如果不指定匹配规则

则默认匹配文中的所有行,如果不指定执行命令,则默认会把匹配到的所有行输出

 

awk的匹配规则

匹配规则可是以下的任意一个

1./正则表达式/:使用通配符的扩展集

2.关系表达式:使用运算符进行操作,可以是字符串或者数字的比较测试

3.模式匹配表达式:用运算符~和~!匹配和不匹配

BEGIN语句块,pattern语句块,END语句块

awk中分号和逗号的区别:

 

awk中如何打印单引号和双引号

 

 

awk脚本的基本结构

awk BEGIN{command} pattern{command} END{comman} filename

BEGIN 在AWK从输入流中读取行之前被执行,是可选的语句块,比如变量通常可以写在BEGIN语句块中

pattern 这个语句块中的通用命令是最重要的部分,但也是可选的,如果没有匹配到,则默认执行print即是打印每一个读取到的行

END语句块在awk从输入流中独取完所有行之后被执行,比如:打印完所需要的行之后,需要一个信息汇总情况,这个时候就可以卸载END语句里

 

awk的工作原理

第一步:执行BEGIN{}语句块中的语句

第二步:从文件或者标准输入stdin读取一行,然后执行pattern语句块,它将逐行扫描文件,从第一行到最后一行重复这个过程,之道文件全部被读取完毕

第三步:当读至输入流末尾,执行END语句块

awk中的变量

变量名作用
$0执行过程中当前行 的所有文本内容
$n以xx为分隔符,当前行的第n个字段,$1为第一个字段…
FS输入 字段 分隔符,默认为空白字符(搭配BEGIN语句块使用)
OFS输出 字段 分隔符,默认为空白字符(搭配BEGIN语句块使用)
RS输入 记录 分隔符,默认为换行符(搭配BEGIN语句块使用)
ORS输出 记录 分隔符,默认为换行符(搭配BEGIN语句块使用)
NR当前行号,从1开始;如果仅处理一个文件,可以将NR的值当为此文件的行号
FNR用法同 NR 一样,不过是用来处理多个文件
NF每一行中字段的总数
$NF每行中最后一个字段
$(NF-1)每行中的倒数第二个字段,以此类推 $(NF-2)为倒数第三
FILENAME当前正在被处理的文件的文件名,一般结合 END{print FILENAME}语句块使用
FILEWIDTHS由空格隔开iade定义了每个字段的宽度,即取代FS,由字段长度来决定如何分割字段的
ARGC命令行中参数的数量,包括 awk 自己。结合 END{commands}语句块使用
ARGV用法: END{print ARGV[0]} ,0表示命令行中的所有参数中的第一个,1为第二个

自定义变量

定义方式 -v var_name = value  -v 变量名=值

 

内建变量的使用例子

1.$0,$n 由之前的例子可以知道,0代表输出整行,n代表打印该行的第几个字段

2FS和OFS

1.需要搭配BEGIN语句块使用,FS相当于-F参数,当FS与OFS(输出 字段 分隔符)在一起使用时,需要用;分开,当打印数据字段变为$0时,FS和OFS不生效

 

FS和OFS针对一行记录而言,RS和ORS 是对所有记录进行分割

输入 记录 分隔符,默认为换行符(搭配BEGIN语句块使用)

 

NR FNR NF使用说明

 

由图可知,当处理多个文件的时候,NR 会将多个文件的行号合并为一个文件的行号,而 FNR 会将多个文件的行号分开表示!

NF $NF $(NF-1)

FILENAME使用方法

awk常用的操作符

算数运算符
  
运算符作用
+   -   *   /加、减、乘、除
%求余
+   -  一元加减(正负号)
++   --增加 或 减少(前置或后置)
^次方 或 平方(a^2 : a的二次方)

awk逻辑运算符 

逻辑运算符 
   
运算符作用解释
&&逻辑和双方都为真才成立
||逻辑或只要有一个为真就成立
逻辑非(非真即假)!true =flase

awk赋值运算符

 

赋值运算符 
运算符作用举例
=单独一个等号就是赋值a=30 变量名=变量值
+=a+=2,相当于 a=a+2
-=a-=3,相当于 a=a-3
*=
/=
%=
awk关系运算符 
  
<   <=  >  >=   ==   !=小于、小于等于、大于、大于等于、等于、不等于
awk正则运算符 
~匹配正则表达式
~!不匹配正则表达式

awk数组以及去重原理

 在其他语言中,你可能习惯的提前声明数组,但是在 awk 中不需要提前声明,直接为 数组中的元素赋值即可!而且 awk 中使用 “数字下标” 的时候,默认是以 1 开始,并不是以0 开始,这里是因为一个函数(split),这边会在函数中提到具体为什么,以及如何使用。

数组的元素设置:

       数组的元素设置为空 是允许的! 当你判断某个元素是否存在的时候,不应该看他数组元素是不是为空!

       当一个元素不存在于数组 的时候,如果我们直接引用此不存在的数组元素,那么awk会自动创建这个元素并默认为此元素赋值为“空字符串”。

示例如下:

使用 awk for循环 和 数组 实现 去重功能:(sort 、uniq、tr 功能)

当"变量的值为字符串"的时候,也"可以进行自加运算",不过,"字符串会被当成数字0"来进行运算

然后,我们就可以利用这一点来统计某些字符出现的次数:

在上面的命令行中,使用了两个模式:"空模式 和 END模式";

在空模式中,我们随便创建了一个数组名为 “a” ,并将文件中“$2” 位置的值 作为了下标,进行引用;

当执行第一行的时候,我们引用的是 a["red"](文件中第一行第二个字段的值),很明显这个元素并不存在,所以:

其一开始的值为“0”,但是当第一行被处理完后,a["red"] 的值 已经被赋值为 1 了。

"由于 END 模式 中的动作会最后执行,所以我们先不考虑END模式;"

这时,空模式中的动作继续处理第二行,而第二行的第三个字段为"yellow",第一次出现的"颜色下标"参与运算的过程与上述同理!

然后当遇到相同的 "颜色下标" 的时候,他们对应的元素的值 都会 "+1","每遇到一次,就 +1"

直到处理完所有的行,开始执行 "END模式 中的 动作"

"此时,a数组中的下标为:第二字段,元素的值即为:第二字段出现的次数"

当然也使用 uniq 和 sort 来实现一下去重排序:

sort先进行排序,使得重复的行紧邻在一起,然后使用uniq去除相邻的重复行,-c选项,显示输出中,在每行行首加上本行在文件中出现的次数

AWK逻辑判断

1、这是 “if…else…” 的语法

{if($3<500){print}else{}}
 
if (条件)
{
语句1;
语句2;

}
else
{
语句1;
语句2;

}

2、这是 “if…else if…else” 的语法:
 
if (条件1)
{
语句1;
语句2;

}
else if(条件2)
{
语句1;
语句2;

}
else
{
语句1;
语句2;

}

for语句

格式1:
for (初始化;布尔表达式;表达式)
{
语句…
}
格式2:
for(变量 in 数组)
{
语句…
}

awk -F"\t" 'BEGIN{OFS="\t"};NR==FNR{a[$1]=$2;next;}NR>FNR{if($3 in a) print $0,a[$3]}' model_category dragon_data | awk -F"\t" '{a[$1]+=$4}END{for(i in a) print i"\t"a[i]}'

while 的语法格式:

while(布尔表达式){
语句…

}  
do while 循环语法:    
do {
代码语句…
}
while(条件)

while 循环实例:

continue,break,exit,next,next使用

nextfile —— 跳过当前文件

nextfile 表示: 在某条件的时候跳过,但是不再执行此文件,立马跳到下一个文件执行!但是下一个文件执行的话,使用的还是同一个条件!

关于print与printf的使用

关于 print

print 我们都知道,它是 awk 中最常用的动作,根据 awk 的匹配规则,匹配到需要的数据,然后使用 print 打印出来!

print在打印字段的时候,需要使用 “,”(逗号) 隔开字段 ,各个字段都会 自动转换成字符串格式,然后根据 自定义的内置变量“OFS”(默认值为 空格) 的值来连接输出的各个字段的字符串!

print 要输出的数据被称之为 “记录”,在print 输出时,会在后面自动加上 输出记录分隔符“ORS” ,它的值默认为换行符 “\n”。

关于printf

准确的说,printf 是根据我们自己设定的格式来输出文本。然鹅,说到输出文本,就会想到另一个常用输出命令:echo。

很清楚的看到,echo 自动给输出的文本进行换行,而 printf 却没有。如果想换行只能结合换行符 “\n”来换行。

关于 格式化字符:

提到了 printf 就要说说它的搭档们了 —— “格式化字符”。基本上跟C语言中的格式化输出一致

格式替换符作用
%s字符串
%f   %F浮点格式
%g   %G浮点格式 或 科学计数格式(输出为数字自己本身)
%b相对应的参数中包含转义字符时,使用此符号进行替换,对应的转义字符就会被转义
%c显示对应参数的第一个字符
%d   %i转换为 整数,但不是四舍五入的结果(23.999 会输出为 23)
%o将 正整数 识 别为八进制数,然后再转换为十进制的方式输出
%u十进制 … … … …
%x   %X十六进制 … … … … …
%%表示 % 本身

1、关于 %s 的用法:

2、关于 %f/F 的用法:

3、关于 %g  %G 的用法:

4、关于 %c 的用法:

....

AWK内置字符串函数

函数说明
gsub( Ere, Repl, [ In ] )除了正则表达式所有具体值被替代这点,它和 sub 函数完全一样地执行,。
sub( Ere, Repl, [ In ] )用 Repl 参数指定的字符串替换 In 参数指定的字符串中的由 Ere 参数指定的扩展正则表达式的第一个具体值。sub 函数返回替换的数量。出现在 Repl 参数指定的字符串中的 &(和符号)由 In 参数指定的与 Ere 参数的指定的扩展正则表达式匹配的字符串替换。如果未指定 In 参数,缺省值是整个记录($0 记录变量)。
index( String1, String2 )在由 String1 参数指定的字符串(其中有出现 String2 指定的参数)中,返回位置,从 1 开始编号。如果 String2 参数不在 String1 参数中出现,则返回 0(零)。
length [(String)]返回 String 参数指定的字符串的长度(字符形式)。如果未给出 String 参数,则返回整个记录的长度($0 记录变量)。
blength [(String)]返回 String 参数指定的字符串的长度(以字节为单位)。如果未给出 String 参数,则返回整个记录的长度($0 记录变量)。
substr( String, M, [ N ] )返回具有 N 参数指定的字符数量子串。子串从 String 参数指定的字符串取得,其字符以 M 参数指定的位置开始。M 参数指定为将 String 参数中的第一个字符作为编号 1。如果未指定 N 参数,则子串的长度将是 M 参数指定的位置到 String 参数的末尾 的长度。
match( String, Ere )在 String 参数指定的字符串(Ere 参数指定的扩展正则表达式出现在其中)中返回位置(字符形式),从 1 开始编号,或如果 Ere 参数不出现,则返回 0(零)。RSTART 特殊变量设置为返回值。RLENGTH 特殊变量设置为匹配的字符串的长度,或如果未找到任何匹配,则设置为 -1(负一)。
split( String, A, [Ere] )将 String 参数指定的参数分割为数组元素 A[1], A[2], . . ., A[n],并返回 n 变量的值。此分隔可以通过 Ere 参数指定的扩展正则表达式进行,或用当前字段分隔符(FS 特殊变量)来进行(如果没有给出 Ere 参数)。除非上下文指明特定的元素还应具有一个数字值,否则 A 数组中的元素用字符串值来创建。
tolower( String )返回 String 参数指定的字符串,字符串中每个大写字符将更改为小写。大写和小写的映射由当前语言环境的 LC_CTYPE 范畴定义。
toupper( String )返回 String 参数指定的字符串,字符串中每个小写字符将更改为大写。大写和小写的映射由当前语言环境的 LC_CTYPE 范畴定义。
sprintf(Format, Expr, Expr, . . . )根据 Format 参数指定的 printf 子例程格式字符串来格式化 Expr 参数指定的表达式并返回最后生成的字符串。

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值