awk是一种可以处理数据,产生格式化报表的语言,功能相当强大。
awk的工作方式是读取数据文件,将每一行数据视为一条记录(record),每笔记录以字段分隔符,分成若干字段,然后输出各个字段的值
awk擅长文本格式化。并将格式化以后的文本输出,而对于文本的处理
awk是逐行处理的,逐行处理的意思就是,当awk处理一个文本时,会一行一行进行处理,处理完当前行,再处理下一行
awk默认以"换行符"为标记,识别每一行,也就是说,awk每次遇到"回车换行",就认为是当前行的结束,新的一行的开始
awk会按照用户指定的分割符去分割当前行,如果没有指定分割符,默认使用空格作为分隔符



awk处理文本的方式图
$0表示显示整行
$NF表示当前行分割后的最后一列
$0跟$NF都是内置变量,注意:$0跟$NF要表达的意思是不一样的
对于awk来说,$NF表示最后一个字段
$NF表示当前行被分隔符切开以后,一共有几个字段,也就是说,假如一行文本被空格分成了7段,那么$NF的值就是$7,而$7表示当前行的第7个字段,也就是最后一列
那么每行的倒数第二列也可以写为($NF-1)

awk只能处理结构化的文本,因此对输入文件的要求是有规则和结构化的,awk将每个输入文本行定义为记录,行中的每个字符串定义为域,域之间用空格,Tab键或其他符号进行分割,分割域的符号就叫做分割符



示例
这是文本中的一行内容
以空格符作为分隔符的话,那这行内容就会被切成9个域,最后一个域的值:madness 888888888,这样子大家也知道了吧
以Tab键作为分隔符的话,那这行内容就会被切成2个域,第一个域的值:There is a fine line between genius and madness,第二个域的值:888888888



awk对每一条记录,都会套用一个"条件类型{操作动作}",如果该文本行符合条件,就执行指定的操作
条件类型或操作动作之一,可以省略

只有条件类型时:表示要显示符合条件的数据行
只有操作动作时:表示对每一数据行都执行该动作操作

注意:awk是以"行"为一次处理的单位,而以域为最小的处理单位







awk处理流程

  1. 读入第一行,并将第一行的数据填入$0,$1,$2......等变量当中
  2. 依据"条件类型"的限制,判断是否需要进行后面的"动作"
  3. 做完所有的动作跟条件类型
  4. 若还有后续的"行"数据,则重复上面1-3的步骤,直到所有数据都读完为止







awk常用格式

  1. awk"条件类型"文件:把符合条件类型的数据行显示出来。
  2. awk'{操作动作}':对每一行都执行{}中的操作
  3. awk'条件类型{操作动作}'文件:对符合条件类型的数据行,执行{}中的操作
  4. awk'条件类型1{操作动作1}条件类型2{操作动作2}......'文件



awk [-F|-f|-v] ‘BEGIN{} //{command1; command2} END{}’ file

[-F|-f|-v]: 大参数,-F指定分隔符,-f调用脚本,-v定义变量 var=value

' ' : 引用代码块

BEGIN: 初始化代码块,在对每一行进行处理之前,初始化代码,主要是引用全局变量,设置FS分隔符

//: 匹配代码块,可以是字符串或正则表达式

{}: 命令代码块,包含一条或多条命令

;: 多条命令使用分号分隔

END : 结尾代码块,在对每一行进行处理之后再执行的代码块,主要是进行最终计算或输出结尾摘要信息



$0: 表示整个当前行

$1: 每行第一个字段

NF: 字段数量变量

NR: 每行的记录号,多文件记录递增

FNR: 与NR类似,不过多文件记录不递增,每个文件都从1开始

t: 制表符

n: 换行符

FS: BEGIN时定义分隔符

RS: 输入的记录分隔符, 默认为换行符(即文本是按一行一行输入)

~ : 匹配,与==相比不是精确比较

!~: 不匹配,不精确比较

==: 等于,必须全部相等,精确比较

!=: 不等于,精确比较

&&: 辑与

||: 逻辑或

  • : 匹配时表示1个或1个以上

/0-9+/: 两个或两个以上数字

/0-9*/: 一个或一个以上数字

FILENAME: 文件名

OFS: 输出字段分隔符, 默认也是空格,可以改为制表符等

ORS: 输出的记录分隔符,默认为换行符,即处理结果也是一行一行输出到屏幕

-F'[:#/]': 定义三个分隔符



//匹配代码块

//纯字符匹配 !//纯字符不匹配 ~//字段值匹配 !~//字段值不匹配 ~/a1|a2/字段值匹配a1或a2

awk '/mysql/' /etc/passwd

awk '/mysql/{print }' /etc/passwd

awk '/mysql/{print $0}' /etc/passwd ##三条指令结果一样

awk '!/mysql/{print $0}' /etc/passwd ##输出不匹配mysql的行

awk '/mysql|mail/{print}' /etc/passwd

awk '!/mysql|mail/{print}' /etc/passwd

awk -F: '/mail/,/mysql/{print}' /etc/passwd ##区间匹配

awk '/2[7]*/{print $0}' /etc/passwd ##匹配包含27为数字开头的行,如27,277,2777...

awk -F: '$1~/mail/{print $1}' /etc/passwd ##$1匹配指定内容才显示

awk -F: '{if($1~/mail/) print $1}' /etc/passwd ##与上面相同

awk -F: '$1!~/mail/{print $1}' /etc/passwd ##不匹配

awk -F: '$1!~/mail|mysql/{print $1}' /etc/passwd



print 是awk打印指定内容的主要命令
awk '{print}' /etc/passwd == awk '{print $0}' /etc/passwd

awk '{print " "}' /etc/passwd ##不输出passwd的内容,而是输出相同个数的空行,进一步解释了awk是一行一行处理文本

awk '{print "a"}' /etc/passwd ##输出相同个数的a行,一行只有一个a字母

awk -F":" '{print $1}' /etc/passwd

awk -F: '{print $1; print $2}' /etc/passwd ##将每一行的前二个字段,分行输出,进一步理解一行一行处理文本

awk -F: '{print $1,$3,$6}' OFS="t" /etc/passwd ##输出字段1,3,6,以制表符作为分隔符



-F指定分隔符

$1 指指定分隔符后,第一个字段,$3第三个字段, t是制表符

一个或多个连续的空格或制表符看做一个定界符,即多个空格看做一个空格

awk -F":" '{print $1}' /etc/passwd

awk -F":" '{print $1 $3}' /etc/passwd ##$1与$3相连输出,不分隔

awk -F":" '{print $1,$3}' /etc/passwd ##多了一个逗号,$1与$3使用空格分隔

awk -F":" '{print $1 " " $3}' /etc/passwd ##$1与$3之间手动添加空格分隔

awk -F":" '{print "Username:" $1 "\t\t Uid:" $3 }' /etc/passwd ##自定义输出

awk -F: '{print NF}' /etc/passwd ##显示每行有多少字段

awk -F: '{print $NF}' /etc/passwd ##将每行第NF个字段的值打印出来

awk -F: 'NF==4 {print }' /etc/passwd ##显示只有4个字段的行

awk -F: 'NF>2{print $0}' /etc/passwd ##显示每行字段数量大于2的行

awk '{print NR,$0}' /etc/passwd ##输出每行的行号

awk -F: '{print NR,NF,$NF,"\t",$0}' /etc/passwd ##依次打印行号,字段数,最后字段值,制表符,每行内容

awk -F: 'NR==5{print}' /etc/passwd ##显示第5行

awk -F: 'NR==5 || NR==6{print}' /etc/passwd ##显示第5行和第6行

route -n|awk 'NR!=1{print}' ##不显示第一行







实例

查找passwd文件中包含nginx的数据行

awk '/nginx/' /etc/passwd

运行结果

nginx:x:996:994:Nginx web server:/var/lib/nginx:/sbin/nologin



查看passwd文件中的每行的第一列跟第二列,不指定分割符,默认以空格为分割符

awk '{ print $1,$2 }' /etc/passwd

运行结果

root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
......略



查看passwd文件中的每行中的第一列跟第二列包含"nginx"的数据行,不指定分割符,默认以空格为分割符

awk '/nginx/{ print $1,$2 }' /etc/passwd

运行结果

nginx:x:996:994:Nginx web



使用选项-F,指定":"为分隔符,查看nginx账号的第三列跟第四列的信息

awk -F: '/nginx/{print $3,$4}' /etc/passwd

运行结果

996 994



以":"为分隔符,+_+为输出字段分隔符(把输出的字段用+_+拼接起来),将nginx账号的第一至五列显示出来

awk -F: 'BEGIN{OFS="+_+"}/nginx/{print $1,$2,$3,$4,$5}' /etc/passwd

运行结果

nginx+_+x+_+996+_+994+_+Nginx web server

注意:BEGIN{}区域指示awk一开始先做初始化的操作,即设定OFS=”+_+“,变量OFS的作用是存储输出字符的分隔符,接着寻找nginx账号所在行,找到后,使用print打印出第一至五列的字段,彼此用"+_+"隔开



组合命令:取网卡中的IP

ifconfig | grep 'inet' | grep -v '127.0.0.1' | awk '{print $2}'

运行结果

192.168.1.60



组合命令:取网络设备名称

cat /proc/net/dev | awk -F: '/eth.:/{print $1}'

运行结果

eth0

取内存文件中的物理内存数

cat /proc/meminfo | awk '/MemTotal/{print $2}'

运行结果

16267660
扫描二维码,在手机上阅读!

本文由 心态很重要 创作,采用 知识共享署名 3.0,可自由转载、引用,但需署名作者且注明文章出处。

2 条评论

  1. 云汇算
    云汇算

    http://zjwave.com

    1. 心态很重要
      心态很重要

      可做友链

添加新评论