AWK

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AWK相关的知识,希望对你有一定的参考价值。

一、介绍

awk是一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入(stdin)、一个或多个文件,或其它命令的输出。它支持用户自定义函数和动态正则表达式等先进功能,是linux/unix下的一个强大编程工具。它在命令行中使用,但更多是作为脚本来使用。awk有很多内建的功能,比如数组、函数等,这是它和C语言的相同之处,灵活性是awk最大的优势。
awk:Aho, Weinberger, Kernighan,报告生成器,格式化文本输出
有多种版本:New awk(nawk),GNU awk( gawk)
gawk:模式扫描和处理语言

?
1、awk的命令格式和选项

awk [options] ‘script‘ var=value file(s)
awk [options] -f scriptfile var=value file(s)
awk [options] ‘BEGIN{ action;… } pattern{ action;… } END{ action;… }‘ file ... 

awk 程序通常由:BEGIN语句块、能够使用模式匹配的通用语句块 、END语句块,共3部分组成
program通常是被单引号或双引号中 

选项:
-F fs   fs指定输入分隔符,fs可以是字符串或正则表达式,如-F:
-v var=value   赋值一个用户定义变量,将外部变量传递给awk
-f scripfile  从脚本文件中读取awk命令
-m[fr] val   对val值设置内在限制,-mf选项限制分配给val的最大块数目;-mr选项限制记录的最大数目。这两个功能是Bell实验室版awk的扩展功能,在标准awk中不适用。

格式:
awk [options] ‘program‘ file… 
program:pattern{action statements;..} (程序 模式 {动作 语句})

“pattern和action: 
pattern部分决定动作语句何时触发及触发事件 
BEGIN,END 
action statements对数据进行处理,放在{}内指明 
print, printf 

awk脚本基本结构
awk ‘BEGIN{ print "start" } pattern{ commands } END{ print "end" }‘ file
一个awk脚本通常由:BEGIN语句块、能够使用模式匹配的通用语句块、END语句块3部分组成,这三个部分是可选的。任意一个部分都可以不出现在脚本中,脚本通常是被单引号或双引号中,例如:
awk ‘BEGIN{ i=0 } { i++ } END{ print i }‘ filename
awk "BEGIN{ i=0 } { i++ } END{ print i }" filename ”

分割符、域和记录 
awk执行时,由分隔符分隔的字段(域)标记$1,$2..$n称 为域标识。$0为所有域,注意:和shell中变量$符含义不同 
文件的每一行称为记录 
省略action,则默认执行 print $0 的操作

?
2、awk的工作原理

awk ‘BEGIN{ commands } pattern{ commands } END{ commands }‘
第一步:执行BEGIN{ commands }语句块中的语句;
?
第二步:从文件或标准输入(stdin)读取一行,然后执行pattern{ commands }语句块,它逐行扫描文件,从第一行到最后一行重复这个过程,直到文件全部被读取完毕。
?
第三步:当读至输入流末尾时,执行END{ commands }语句块。
?


可以看到此图片中1带有BEGIN语句并且后面跟了文件,但显示结果只有{}内容,而标记2则没有BEGIN语句但打印出了3行“hello,awk”,原来文件中也就三行,由此可以看出BEGIN语句它是读取文件之前执行这个语句,和文件没关系。

技术分享图片
?
?
BEGIN语句块在awk开始从输入流中读取行之前被执行,这是一个可选的语句块,比如变量初始化、打印输出表格的表头等语句通常可以写在BEGIN语句块中。
??
?技术分享图片
??
?技术分享图片
??
END语句块在awk从输入流中读取完所有的行之后即被执行,比如打印所有行的分析结果这类信息汇总都是在END语句块中完成,它也是一个可选语句块。(文件执行完END再处理,后面必须有文件)
?
pattern语句块中的通用命令是最重要的部分,它也是可选的。如果没有提供pattern语句块,则默认执行{ print },即打印每一个读取到的行,awk读取的每一行都会执行该语句块。

?
3、awk量

变量:内置和自定义变量 
FS:输入字段分隔符,默认为空白字符 
    awk -v FS=‘:‘  ‘{print $1,FS,$3}‘ /etc/passwd 
    awk –F:   ‘{print $1,$3,$7}‘ /etc/passwd 
OFS:输出字段分隔符,默认为空白字符 
    awk -v FS=‘:’  -v OFS=‘:’ ‘{print $1,$3,$7}‘ /etc/passwd 
RS:输入记录分隔符,指定输入时的换行符,原换行符仍有效   (在RS中行不等于记录,分隔符之间忽略行才是)
    awk -v RS=‘ ‘ ‘{print }‘ /etc/passwd
ORS:输出记录分隔符,输出时用指定符号代替换行符 
    awk -v RS=‘ ‘ -v ORS=‘###‘‘{print }’ /etc/passwd
NF:字段数量 
    awk -F: ‘{print NF}’ /etc/fstab,引用内置变量不用$ 
    awk -F:  ‘{print $(NF-1)}‘  /etc/passwd 
NR:行号 
    awk ‘{print NR}‘  /etc/fstab ; awk END‘{print NR}‘  /etc/fstab

技术分享图片


技术分享图片
RS
技术分享图片
ORS
技术分享图片

FNR:各文件分别计数,行号  (NR会统计所有,FNR分别计算)
    awk ‘{print FNR}‘  /etc/fstab /etc/inittab 
FILENAME:当前文件名 
    awk ‘{print FILENAME}‘  /etc/fstab 
ARGC:命令行参数的个数 
    awk ‘{print ARGC}‘  /etc/fstab /etc/inittab 
    awk ‘BEGIN {print ARGC}‘  /etc/fstab /etc/inittab 
ARGV:数组,保存的是命令行所给定的各参数 
    awk ‘BEGIN {print ARGV[0]}‘  /etc/fstab /etc/inittab
    awk ‘BEGIN {print ARGV[1]}‘  /etc/fstab /etc/inittab

技术分享图片

自定义变量(区分字符大小写) 
(1) -v var=value 
(2) 在program中直接定义 
示例: 
    awk -v test=‘hello gawk‘ ‘{print test}‘ /etc/fstab 
    awk -v test=‘hello gawk‘ ‘BEGIN{print test}‘ 
    awk ‘BEGIN{test="hello,gawk";print test}‘ 
    awk -F: ‘{sex="male";print $1,sex,age;age=18}‘ /etc/passwd
cat awkscript 
{print script,$1,$2} 
awk -F: -f awkscript script=“awk” /etc/passwd

技术分享图片
?技术分享图片

?
4、printf命令

格式化输出:printf “FORMAT”, item1, item2, ... 
    (1) 必须指定FORMAT
    (2) 不会自动换行,需要显式给出换行控制符,\n
    (3) FORMAT中需要分别为后面每个item指定格式符 
格式符:与item一一对应 
    %c: 显示字符的ASCII码 
    %d, %i: 显示十进制整数 
    %e, %E:显示科学计数法数值 
    %f:显示为浮点数 
    %g, %G:以科学计数法或浮点形式显示数值 
    %s:显示字符串 
    %u:无符号整数 
    %%: 显示%自身 
修饰符: 
    #[.#]:第一个数字控制显示的宽度;第二个#表示小数点后精度,%3.1f 
    -: 左对齐(默认右对齐) %-15s 
    +:显示数值的正负符号 %+d

?技术分享图片

printf示例 
    awk -F: ‘{printf "%s",$1}‘ /etc/passwd 
    awk -F: ‘{printf "%s\n",$1}‘ /etc/passwd
    awk -F: ‘{printf "%-20s %10d\n",$1,$3}‘ /etc/passwd 
    awk -F: ‘{printf "Username: %s\n",$1}‘  /etc/passwd 
    awk -F: ‘{printf "Username: %s,UID:%d\n",$1,$3}‘ /etc/passwd 
    awk -F: ‘{printf "Username: %15s,UID:%d\n",$1,$3}‘ /etc/passwd 
    awk -F: ‘{printf "Username: %-15s,UID:%d\n",$1,$3}‘ /etc/passwd


5、操作符

算术操作符: 
    x+y, x-y, x*y, x/y, x^y, x%y 
    -x: 转换为负数 
    +x: 转换为数值 
字符串操作符:没有符号的操作符,字符串连接 
赋值操作符: 
    =, +=, -=, *=, /=, %=, ^= 
    ++, --
比较操作符: 
    ==, !=, >, >=, <, <=
模式匹配符:~:左边是否和右边匹配包含 !~:是否不匹配 
    awk –F: ‘$0 ~ /root/{print $1}‘  /etc/passwd 
    awk ‘$0~“^root"‘ /etc/passwd 
    awk ‘$0  !~ /root/‘   /etc/passwd 
    awk –F: ‘$3==0’  /etc/passwd

技术分享图片
~ and !~
技术分享图片


技术分享图片

二、后续待定

以上是关于AWK的主要内容,如果未能解决你的问题,请参考以下文章

awk

在awk代码中引用shell变量的方法

精通awk系列:awk读取行的细节

awk 脚本帮助 - 逻辑问题

linux awk命令的使用

sh 使用awk删除可执行代码的有效负载