shell脚本中awk应⽤,数组的定义使⽤
1、awk的基础应⽤
1.1,概念
除了使⽤ sed 命令,Linux 系统中还有⼀个功能更加强⼤的⽂本数据处理⼯具,就是 awk。它诞⽣于 20 世纪 70 年代末期,这也许是它影响了众多 Linux ⽤户的原因之⼀。
AWK是⼀种优良的⽂本处理⼯具,Linux及Unix环境中现有的功能最强⼤的数据处理引擎之⼀。awk命名: Aho、Weingberger 和Kernighan三个⼈的姓的缩写。
awk也是⼀个数据处理⼯具!相较于 sed 常常作⽤于⼀整个⾏的处理, awk 则⽐较倾向于⼀⾏当中分成数个字段来处理。
和 sed 命令类似,awk 命令也是逐⾏扫描⽂件(从第 1 ⾏到最后⼀⾏),寻含有⽬标⽂本的⾏,如果匹配成功,则会在该⾏上执⾏⽤户想要的操作;反之,则不对⾏做任何处理。
1.1.2,awk
在linux上常⽤的是gawk,awk是gawk的链接⽂件
awk 的强⼤之处在于commands,它由2部分组成,分别为匹配规则和执⾏命令,如下所⽰:
‘匹配规则{执⾏命令}’
awk命令的完整格式:awd [-F field-separator] ‘匹配规则{执⾏命令}’ filename
这⾥的匹配规则,和 sed 命令中的匹配规则部分作⽤相同,⽤来指定执⾏命令可以作⽤到⽂本内容中的具体⾏(匹配条件),可以使⽤字符串(⽐如 /demo/,表⽰查看含有demo字符串的⾏)或者正则表达式指定。另外需要注意的是,整个commands是⽤单引号(’’)括起,⽽其中的执⾏命令部分需要⽤⼤括号({})括起来。
举个简单的例⼦:
[root@localhost ~]# awk '/^KaTeX parse error: Expected group after '^' at position 41: … 在此命令中,/^/ 是⼀个正则表达式,功能是匹配⽂本中的空⽩⾏,同时可以看到,执⾏命令使⽤的是 print 命令,此命令经常会使⽤,它的作⽤很简单,就是将指定的内容进⾏输出。因此,整个命令的功能是,如果 有 N 个空⽩⾏,那么执⾏此命令会输出 N 个 Blank line。
注:在 awk 程序执⾏时,如果没有指定执⾏命令,则默认会把匹配的⾏输出;如果不指定匹配规则,则默认匹配⽂本中所有的⾏。
1.1.4,'匹配规则{执⾏命令}'
任何awk语句都是由’匹配规则{执⾏命令}‘组成,⼀个awk中可以有多个语句。匹配规则决定执⾏命令的执⾏条件。
例如上⾯举的例⼦中’/^KaTeX parse error: Expected group after '^' at position 26: …Blank line"}',/^/就是匹配规则,print就是执⾏命令,当⽂件中有匹配/^$/条件的⾏是就会执⾏pirnt命令。
1.1.5,匹配规则(即执⾏条件):
⼀般使⽤关系表达式作为条件。这些关系表达式⾮常多,具体参考下表:
条件类型 条 件 说 明
awk保留字 BEGIN 在awk程序⼀开始,尚未读取任何数据之前执⾏。BEGIN 后的动作只在程序开始时执⾏⼀次
awk保留字 END 在awk程序处理完所有数据,即将结束时执⾏。END 后的动作只在程序结束时执⾏⼀次
关系运算符 > ⼤于
< ⼩于
>= ⼤于等于
<= ⼩于等于
== 等于。⽤于判断两个值是否相等。如果是给变童赋值,则使⽤"=”
!= 不等于
匹配表达式 ~(匹配) value ~ /regexp/ 如果value匹配/regexp/,则返回真
!~(不匹配) value !~ /regexp/ 如果value不匹配/regexp/,则返回真
正则表达式 /正则表达式/ 如果在“//”中可以写⼊字符,则也可以⽀持正则表达式,如:/root/表⽰匹配含有root的⾏。
逻辑运算符 && 逻辑与
|| 逻辑或
例如:
[root@localhost ~]# awk -F: ‘/ {print $1}’ /etc/passwd
linux循环执行命令脚本判断/
[root@localhost ~]# awk -F: ‘/ {print $1}’ /etc/passwd
判断/
1.1.6,awk 使⽤数据字段变量
前⾯说过,在 awk 中,默认的字段分隔符是任意的空⽩字符(例如空格或制表符)。 在⽂本⾏中,每个数据字段都是通过字段分隔符划分的(-F选项指定的分隔符)。awk 在读取⼀⾏⽂本时,会⽤预定义的字段分隔符划分每个数据字段。如/etc/passwd⽂件中可以将“:”当做字段分隔符,共划分成7个数据字段。
awk 的主要特性之⼀是其处理⽂本⽂件中数据的能⼒,它会⾃动给⼀⾏中的每个数据字段分配⼀个变量。
默认情况下,awk 会将如下变量分配给它在⽂本⾏中发现的数据字段:
$0 代表整个⽂本⾏;
$1 代表⽂本⾏中的第 1 个数据字段;
KaTeX parse error: Unexpected character: ' ' at position 21: …本⾏中的第 2 个数据字段; n 代表⽂本⾏中的第 n 个数据字段。
所以在下⾯的例⼦中,awk 程序读取⽂本⽂件,只显⽰第 1 个数据字段的值:
[root@localhost ~]#
One line of test text.
Two lines of test text.
Three lines of test text.
[root@localhost ~]# awk ‘{print $1}’ //把⽂件中每⾏的空格当做分隔符
One
Two
Three
本例中⽤$1字段变量来表⽰第1个数据字段。当然,如果你要读取采⽤了其他字段分隔符的⽂件,可以⽤ -F 选项⼿动指定。
1.1.7,执⾏命令(动作action):
awk的执⾏命令在⼤括号{ }内指明。动作⼤多数⽤来打印(即print指令),但是还有些更长的代码诸如i f和循环语句及循环退出结构。如果不指明采取动作,awk将打印出所有浏览出来的记录。
动作(Action):
格式化输出(print);
流程控制语句(if、while、for等);
例如:显⽰passwd⽂件中第1个第6个字段的信息
1.1.8,awk中的BEGIN和END
语法:awk [options] ‘BEGIN{ print “start” } 匹配规则{ commands } END{ print “end” }’ filename
7 /bash 7(第7个数据字段)的值是否匹配正则表达式/bash 7! /bash 7(第7个数据字段)的值是否不匹配正则表达式/bash
其中:BEGIN END是AWK的关键字,因此必须⼤写;这两个部分开始块和结束块是可选的
BEGIN模块:BEGIN 的执⾏时机是"在 awk 程序⼀开始,尚未读取任何数据之前"。⼀旦BEGIN后的动作执⾏⼀次,当awk开始从⽂件中读⼊数据时,BEGIN 的条件就不再成⽴,所以BEGIN定义的动作只能被执⾏⼀次。通过BEGIN开始块我们可以⽤来设置变量,设置标题。
例如:
#这⾥定义了两个动作
#第⼀个动作使⽤BEGIN条件,所以会在读⼊⽂件数据前打印"print username and loginshell" (只会执⾏⼀次)
#第⼆个动作会在条件满⾜时打印⽂件的第1个字段和第7个字段
END模块:END也是awk的保留字,不过刚好和 BEGIN 相反。END 是在 awk 程序处理完所有数据,即将结束时执⾏的。END 后的动作只在程序结束时执⾏⼀次。
例如:
输出结尾输⼊"The End",这并不是⽂档本⾝的内容,⽽且只会执⾏⼀次
1.1.9,AWK⼯作过程:
通过上⾯我们可以知道;AWK它⼯作过程
1.如果BEGIN块存在,awk执⾏它指定的actions。
2.awk从输⼊⽂件中读取⼀⾏,称为⼀条输⼊记录。(如果输⼊⽂件省略,将从标准输⼊读取),awk将读⼊的记录分割成多个字段,将第1个字段放⼊变量$1中,第2个字段放⼊$2,以此类推。$0表⽰整条记录。
3、把当前输⼊记录与awk中’匹配规则{执⾏命令}'中的“匹配规则”⽐较,看是否匹配,如果相匹配,就执⾏对应的‘执⾏命令’。如果不匹配,就跳过对应的执⾏命令。
4、awk读取输⼊的下⼀⾏,继续重复步骤2和3,这个过程⼀直持续,直到awk读取到⽂件尾。
5、当awk读完所有的输⼊⾏后,如果存在END,就执⾏相应的actions。
例如:显⽰最近登录系统的⽤户,要求只显⽰⽤户名和登录源
使⽤last命令可以查看最近登录的⽤户信息。如下图所⽰:
使⽤last命令可以查看最近登录的⽤户信息。如下图所⽰:
使⽤awk命令抽取⽤户名和IP区域的数据
1.2,awk的变量
1.2.10,awk⾃定义变量
⾃定义变量:⽤户⾃⼰定义的变量,有两种形式
1、-v varname=value 变量名区分字符⼤⼩写
例如:统计⽤户数量:
2、在program中直接定义,以下定义了3个⾃定义变量,其实形式像编程语⾔⼀样,定义的时候⽤分号。打印变量跟之前⼀样,⽤逗号隔
开,注意,不需要⽤美元符号。
3、也可以引⽤命令⾏定义的变量
范例:
统计某个⽬录(如/root)下的⽂件占⽤的字节数(以MB显⽰):
注:之前的{}⾥都是只有⼀个print语句,其实print只是⼀个语句,⽽{}可以有多个语句,以;号隔开。
1.2.11,awk内置变量(预定义变量)
awk除了可以⾃定义变量外,awk还提供⼀些内置量,常⽤的内置标量如下:
$n 当前记录(当前⾏)的第n个字段,⽐如n为1表⽰第⼀个字段,n为2表⽰第⼆个字段
$0 这个变量包含执⾏过程中当前⾏的⽂本内容
FILENAME 当前输⼊⽂件的名
FS 字段分隔符(默认是任何空格)
NF 表⽰字段数,在执⾏过程中对应于当前的字段数
NR 表⽰记录数,在执⾏过程中对应于当前的⾏号
FNR 各⽂件分别计数的⾏号
说明:
练习⽂件内容:
[root@localhost ~]#
wangwu 20 man
zhangsan 22 woman
lisi 23 woman
[root@localhost ~]#
chenzhe 20 man
xiaoming 22 woman
lier 23 woman
例1:NF:打印出每⾏有多少列:
如何显⽰最后两列的值呢?
分析:NF变量表⽰每⾏字段数,所以NF的值就是每⾏最后⼀个字段,NF减1就是倒数第⼆个字段。
注:引⽤NF变量,需要⽤美元符号
例2:NR:每⼀⾏的⾏号:
例3:FNR:awk⽀持多⽂件扫描,如果采⽤NR, 下⼀个⽂件的⾏序号会接着上⼀个⽂件,FNR就会单独统计
例4:FS:分隔符
范例1:分隔符的使⽤
⽤法:-F fs 其中fs是指定输⼊分隔符,fs可以是字符串或正则表达式;分隔符默认是空格
常见的写法: -F: -F, -F[aA]
范例2:指定多个分隔符
1.3,实例演⽰
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论