awk的详细用法

awk简介

awk是一种编程语言,也可以说是一个脚本语言解释器,主要是用来实现文本的格式化输出。awk是取了其三位作者名字的首字母,即Aho,WeinbergerKernighan。awk在Linux上是基于GNU协议实现的,即GNU awk,也就是gawk。

awk的工作模式

遍历整个文件,从第一行到最后一行。每次仅读取文件的一行,依照用户指定的输入分隔符进行切片,并将每个分片在awk的内存空间赋予一个内建变量(位置变量)进行保存,然后根据用户指定的pattern寻找匹配特定模式的行,执行处理过程。

awk工作流程.png

awk基本语法格式

gawk [OPTIONS] 'PATTERN{ACTION_STATEMENTS}' FILE...

  • NOTE

    • PATTERN可以是BEGIN、END、表达式等;

    • PATTERN省略则表示匹配所有数据;

    • ACTION_STATEMENT语句之间使用分号分隔;

    • 默认的ACTION是print。

OPTIONS

  • -F fs,–field-separator fs:指明以fs作为输入行的字段分隔符,默认分隔符为空格;

  • -v var=val,–assign var=val:自定义一个变量;

  • -f program-file,–file program-file:指明从指定的脚本文件中读取awk指令。

变量

内建变量

FS:input Field Separator,输入的字段分隔符,默认为空格;
OFS:Output Field Separator,输出的字段分隔符,默认为空格;
RS:input Record Separator,输入时的换行符,默认为\n;
ORS:Output Record Separator,输出时的换行符,,默认为\n;
NF:Number of Field,当前行的字段数量;
NR:Number of Record,输入流的当前记录编号(行数);
FNR:当前输入文档的当前记录编号,多个输入文档时有用;
FILENAME:当前输入文件名;
ARGC:命令行参数的个数;
ARGV:一个数组,保存命令行所给定的各参数。

实例

指明输入的字段分隔符:

# awk -F: '{print $1,$3}' /etc/passwd -->//指定的字段分隔符可以使用引号引起,也可以不用(空格除外),引号可以是单双引号;
# awk -v FS=':' '{print $1,$3}' /etc/passwd -->//指定的字段分隔符可以使用引号引起,也可以不用(空格除外),引号可以是单双引号;
# awk 'BEGIN{FS=":"}{print $1,$3}' /etc/passwd -->//指定的字段分隔符只能使用双引号引起。

NOTE: 指明多个分隔符时使用[],如FS="[:,]"。

自定义变量

  • 变量名区分字母大小写;

  • 可以在ACTION_STATEMENT中定义;

  • 可以在命令行中通过-v选项定义。

实例

# awk -v test='hello gawk' 'BEGIN{print test}' -->//指明变量值时可以使用单双引号;
# awk 'BEGIN{test="hello gawk";print test}' -->//指明变量值时只能用双引号。

NOTE

在引用变量时不要加$符号。

print命令

print item1,item2...

  • NOTE

    • 以逗号作为分隔符;

    • 输出的各item可以是字符串、数值,也可以是当前记录的字段、变量或awk的表达式;

    • 如果省略item,相当于print $0。

printf命令:格式化输出

printf FORMAT, item1, item2, ...

  • NOTE

    • FORMAT必须给出;

    • 不会自动换行,必须显式给出换行控制符\n;

    • FORMAT中需要分别为后面的每个item指定一个格式化符号。

格式符

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

修饰符

#[.#]:第一个数字#控制显示宽度;第二个数字#表示小数点后边的精度;例如,%3.3f。
+:显示数值的符号
-:左对齐

实例

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

操作符

算数操作符

+:加
-:减
*:乘
/:除
%:取余
^:幂运算

字符串操作符:没有符号的操作符,字符串连接

赋值操作符

=:直接赋值
+=:相加后赋值给变量
-=:相减后赋值给变量
*=:相乘后赋值给变量
/=:相除后赋值给变量
++:自加
--:自减

比较操作符

>:大于
<:小于
>=:大于等于
<=:小于等于
==:等于
!=:不等于

模式匹配

~:匹配
!~:不匹配

逻辑操作符

&&:与
||:或
!:非

函数调用

function_name(argu1,argu2,...)

实例

# awk 'BEGIN{print rand()}'

条件表达式

selector?if_true_expression:if_false_expression

实例

# awk -F: '{$3>=1000?usertype="Common User":usertype="Sysadmin or SysUser";printf "%15s:%-s\n",$1,usertype}' /etc/passwd

PATTERN

  • empty:空模式,匹配每一行;

  • /regular expression/:仅处理能被此处模式匹配到的行,对模式取反在其之前加!

  • Relational Expression:关系表达式,结果有“真”有“假”,结果为“真”时才会被处理;

    • 真:结果为非0值,非空字符串

  • line range:行范围

    • startline,stopline: /par1/,/par2/

    • 注意:不支持直接给出数字格式

    • 实例:# awk -F: '(NR>=2&&NR<=10){print $1}' /etc/passwd

  • BEGIN/END模式

    • BEGIN{}:仅在开始处理文本前执行一次

    • END{}:仅在文本处理结束后执行一次

控制语句

if(condition) {statments} 
if(condition) {statments} else {statements}
while(conditon) {statments}
do {statements} while(condition)
for(expr1;expr2;expr3) {statements}
break
continue
delete array[index]
delete array
exit 
{ statements }

注意:

  • 多个语句之间需用分号分隔;

  • 语句之间可实现嵌套,但是需用花括号进行约束;

  • 单个语句时可省略花括号。

if-else

语法:

if(condition) statement [else {statement}]

使用场景:对awk取得的整行或某个字段做条件判断。

实例

# awk -F: '{if($3>=1000) {printf "Common user: %s\n",$1} else {printf "root or Sysuser: %s\n",$1}}' /etc/passwd

while

语法

while(condition) statement

使用场景:对一行内的多个字段逐一类似操作时使用,对数组中的各元素逐一处理时使用。

实例

# awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {if(length($i)>=7) {print $i,length($i)}; i++}}' /etc/grub2.cfg

for循环

语法

for(expr1;expr2;expr3) statement

实例

# awk '/^[[:space:]]*linux16/{for(i=1;i<=NF;i++) {print $i,length($i)}}' /etc/grub2.cfg

特殊用法:能够遍历数组中的元素

for(var in array) {for-body}

break和continue

break:跳出循环

continue:提前结束本轮循环跳转到下一轮,即完成行中的字段间跳转

next:提前结束对本行的处理而直接进入下一行

实例

# awk -F: '{if($3%2!=0) next; print $1,$3}' /etc/passwd

array

关联数组:array[index-expression]

对于index-expression需要注意:

  • 可使用任意字符串,但是需要用双引号;

  • 如果数组元素事先不存在,在引用时,awk会自动创建此元素,并将其值初始化为“空串”。

实例

练习1:统计/etc/fstab文件中每个文件系统类型出现的次数;
~]# awk '/^UUID/{fs[$3]++}END{for(i in fs) {print i,fs[i]}}' /etc/fstab

练习2:统计指定文件中每个单词出现的次数;
~]# awk '{for(i=1;i<=NF;i++){count[$i]++}}END{for(j in count) {print j,count[j]}}' /etc/fstab

内置函数

数值处理

  • rand():返回0和1之间的一个随机数,但是一旦返回该值,再次请求时其值不再改变

字符串处理

  • length([s]):返回指定字符串的长度;

  • split(s,a[,r]):以r为分隔符切割字符s,并将切割后的结果保存至a所表示的数组中;

实例

# netstat -tan | awk '/^tcp\>/{split($5,ip,":");count[ip[1]]++}END{for (i in count) {print i,count[i]}}'

原创文章,作者:Jeason,如若转载,请注明出处:http://www.178linux.com/58288

(0)
JeasonJeason
上一篇 2016-11-14 08:28
下一篇 2016-11-14 08:28

相关推荐

  • MySQL常用字符函数

    MySQL常用字符函数简介 CONCAT(S1,S2…Sn) 连接S1,S2…Sn为一个字符串 concat函数,把传入的参数连接成为一个字符串。 例如: 把“aaa”、“bbb”、”ccc”3个字符串连接成一个字符串,“aaabbbccc”.另外任何与NULL进行连接的结果都将是NULL. >SELEC…

    Linux干货 2017-05-01
  • N25-第九周博客作业

    1、写一个脚本,判断当前系统上所有用户的shell是否为可登录shell(即用户的shell不是/sbin/nologin);分别这两类用户的个数;通过字符串比较来实现; #!/bin/bash # 统计登录用户和非登陆用户的个数 # author: han declare -i loginnum=0 declare -i nologinnum=0 whil…

    Linux干货 2017-02-24
  • Mogilefs使用Nginx实现代理访问

    MogileFS介绍:  MogileFS是一个开源的分布式文件存储系统,由LiveJournal旗下的DangaInteracitve公司研发。可支持文件自动备非的功能,提供高可用性和高可扩展性。 MogileFS组件:  trackers:   MoglieFS的调度器,是mogileFS的核心,访问入口。  功能…

    Linux干货 2015-08-06
  • linux基础之磁盘管理

    linux基础之磁盘管理 学习linux,数据维护和管理是重中之重,而数据大部分存放在硬盘当中,因此,熟练掌握磁盘的使用和管理是运维人员的基础要求。那么,linux系统包括哪些知识点呢? 下面,我们就详细阐述下Linux中磁盘的分区、格式化,以及一些磁盘的高级用法:磁盘配额、RAID阵列和LVM 一、硬盘 随着技术的进步,人类社会的不断发展。硬盘也经历了几代…

    Linux干货 2017-03-19
  • DHCP简介及简单实践

    一、引言 DHCP全称Dynamic Host Configure Protocol,动态主机配置协议,用于向网络中的计算机分配IP地址及一些TCP/IP配置信息。DHCP提供了安全,可靠且简单的TCP/IP网络设置,避免了TCP/IP网络地址的冲突,同时大大降低了工作负担。 二、DHCP工作流程 DHCP采用C/S架构,即Server/Client,它的简…

    Linux干货 2017-01-10
  • IoC/DIP其实是一种管理思想

    关于IoC的的概念提出来已经很多年了,其被用于一种面象对像的设计。我在这里再简单的回顾一下这个概念。我先谈技术,再说管理。 话说,我们有一个开关要控制一个灯的开和关这两个动作,最常见也是最没有技术含量的实现会是这个样子: 然后,有一天,我们发现需要对灯泡扩展一下,于是我们做了个抽象类: 但是,如果有一天,我们发现这个开关可能还要控制别的不单单是灯泡的东西,我…

    Linux干货 2016-08-15