awk 是一门语言,这当之无愧!awk 除了简单的文本处理功能,awk具有计算机语言所特有的性质,例如变量、判断、循环、甚至数组。
简单的功能:
awk 处理文本时,将文本分成一条一条的记录,awk允许通过匹配代码(正则)匹配记录;每条记录都包含多个字段,awk可以修改字段分隔符来灵活的隔开字段。它提供了($0,$1…)访问各个字段。
awk 常被用于处理字段。所谓字段,就是文本文件中,每一行分成许多列,列与列之间用特定的字符隔开。
awk 命令分三部分: awk 本身 、 awk要执行的命令内容 、awk的输入文件。
awk 执行命令时,依次读取每一行,将命令应用到每一行。
– print 和 print $0 行为完全相同,都是打印一整行!
-F 参数设置的是awk的初始化变量FS,FS控制着awk的字段分隔符,默认情况下是空白字符。
awk 支持设置多个字段分隔符,甚至用正则表达式来设置。
eg. awk -F”[\t ]+” // 表示此分隔符匹配一个或多个制表符或空格符
awk读取标准输入。
AWK的代码结构:
awk默认对每一个输入行执行一段代码块。
awk的运行可看成3部分:处理输入前的初始化(BEGIN{}代码块)、处理输入过程({}代码块集合)、处理完所有输入后的扫尾工作(END{}代码块)。
BEGIN代码块,主要完成awk部分参数的初始化操作!
核心处理输入的过程:执行体
END代码块,是在所有输入都处理完成后awk才去运行的代码!
– BEGIN 代码块
格式:BEGIN标签加上{}。
在这个代码块中完成一些变量的初始化操作,只在初始化时被运行一次。
eg.
awk定义FS变量为字段分隔符,在命令行 -F参数用于指定字段分割符,在BEGIN代码段中这样写:
fs.awk // awk 脚本,-f 参数引用脚本到awk命令中
BEGIN{
FS=":" // 将冒号赋给FS变量,改变字段分隔符
}
{
print "USER: " $1 "\tSHELL: " $7
}
head -n10 /etc/passwd |awk -f fs.awk
还可以在命令行直接初始化:
awk 'BEGIN{FS=":"}{print "USER: " $1 "\tSHELL: " $7}'
-F 和 FS 都可以改变字段分隔符,FS适用于awk脚本比较复杂的时候.
– END 代码块:
格式: END{}
所有输入处理完成后才去执行!仅仅执行一次!
END代码块中,awk脚本可以执行一些类似于统计数据、打印输出之类的操作。
eg.
search.awk
BEGIN{ # 初始化信息,便于阅读
print "How many prople with nologin?"
}
/nologin/{++adder} # 核心awk处理过程
END{ # 扫尾工作,打印结果
print "'nologin' appears " adder " times."
}
awk -f search.awk /etc/passwd
– awk的模式匹配
针对BEGIN和END之间的第二部分的核心处理过程而言,只对匹配上的数据做处理!
语法:
/正则表达式/ {匹配后的操作}
awk首先用正则表达式去匹配数据记录,如果匹配上,才执行后面{}内的操作。
eg.1
awk '/^$/{print "This is an empty line."}'/etc/inittab # 匹配空行一次执行一次输出
eg.2
shell_recorder.wak
BEGIN{
print "SHELL USAGE:"
}
/bash/{++bash} //
/nologin/{++nologin}
END{
print "We have " bash " bash users."
print "We have " nologin " nologin users."
}
awk -f shell_recorder.awk /etc/passwd
awk变量
有两种: 用户自定义变量 、内建变量
– awk和绝大多数脚本语言一样,变量使用无需先声明,awk会在第一次使用该变量的时候自动建立变量。
– awk的变量建立时初始值都是空字符串,但是在需要数值时,它会被视为0。即awk会自动将字符串转换为数值进行计算。
在这一点上,awk的行为和shell脚本是一样的。大多数脚本是语言的行为都是这样:变量值存储字符串,当需要时再转换为为其他类型。
命名规则:
awk的变量名必须以ASCII字母或下划线开始,然后选择性的接上字母、数字、下划线。
– 如果用正则表达式来匹配变量名的话,awk的变量名必须匹配[A-Za-z_][A-Za-z_0-9]*
命名建议: 局部变量小写,全局变量第一个字母大写,内建变量全部大写
awk 的常见内建变量
F-field字段,域 R-record记录 S-sign符号 N-number数字
变量 | 说明 |
FILENAME | 当前输入文件的名称 |
FNR | 当前输入文件的记录数 |
NR | 工作中的记录数(行数) |
NF | 一条记录的字段数(列数) |
FS | 字段分隔符(支持正则),默认空格 |
OFS | 输出字段分隔符 |
RS | 输入记录分隔符,默认换行 |
ORS | 输出记录分隔符 |
awk数组
和awk变量一样,无需声明就能使用。
命名规则:和变量名的命名规则相同:[a-zA-Z_][a-zA-Z_0-9]*
数组元素的引用:
awk支持在数组名之后,以方括号将任意数字或字符串表达式扩起来作为引用数组的下标(索引)。其他语言要求数组的下标必须是数字。
eg.
site[google] = “http://www.google.com”
site[yahoo] = “http://yahoo.com”
(类似于键值对的形式,key是下标,value是数组元素)
awk这种能以任意值作为数组的索引(下标)的数组,称为关联数组,因为他们的名称是与值相关联的。
– awk 支持数组的查找、插入、删除操作。
– awk数组的存储空间在引用新元素时会自动增长。
– awk数组的存储空间是稀疏的,插入了第一个元素array[1]后,可直接插入array[1000],不用填满2-999之间的数组元素。
– awk数组的元素值可以为任意类型,无类型限制。
总计:awk数组更像是一系列键值对的集合,只不过打上了数组的标签。
数组的元素的删除:
delete array[index] //删除数组的某一个元素
delete array //删除数组所有元素
系统环境变量
awk支持访问linux系统环境变量,通过ENVIRON数组
eg.
awk ‘BEGIN{print ENVIRON[“HOME”]; print ENVIRON[“PATH”]}’
// 有两个索引是:ENVIRON[“HOME”]、ENVIRON[“HOME”]。
awk在启动时会从系统读取环境变量对数组ENVIRON进行初始化,可以对这个数组进行加入、删除以及修改。
算术运算和运算符
– 算术运算
awk中直接进行算术运算,
支持直接进行算术运算的运算符只有: +(加) -(减) *(乘) /(除) %(取模、求余) ^(幂次方),
例如:
awk 'BEGIN {print "(3+2)*7=" (3+2)*7}'
(3+2)*7=35
awk 'BEGIN {print "3^10=" 3^10}'
3^10=59049
% 是取模运算,表达式 x%y 中,运算结果是x%y的余数。当x能被y整除时,结果为0。
例如:判断闰年
year.txt
1936图灵提出人类历史上第一个人工智能的概念
1946世界上第一台计算机"埃尼阿克(ENIAC)"在美国宾西法尼亚大学诞生
1956第二代计算机产生
1969Ken.ThompsoDernis.Ritchie发布第一版Unix
1979 AT&T从各大学收回Unix版权,此后诞生了System V 和 BSD 两个版本线的Unix操作系统
1983RichardStallman创建GNU(GNU is not Unix.),1983-1991年GNU三大软件:Bash shell、gcc、emacs.
1991LinusTorvalds发布Linux内核
1994Lins加入GNU,GNU系列软件与Linux内核结合,退出linus's minix,简称Linux.
leap.awk
# awk 脚本求闰年
BEGIN {
print "Pick leap years:"
}
{
# $1为记录的第一个字段
year=$1
if(( year %4==0&& year %100!=0)||year %400==0)
print year "is a leap year."
else
print year "is not a leap year."
}
END {
print "Checking is over."
}
awk -f leap.awk year.txt
Pick leap years:
1936is a leap year.
1946is not a leap year.
1956is a leap year.
1969is not a leap year.
1979is not a leap year.
1983is not a leap year.
1991is not a leap year.
1994is not a leap year.
1995is not a leap year.
2016is a leap year.
Checking is over.
– awk运算符
=+=-=*=/=^=**= 赋值 # **= 等价于^=
?: c条件表达式 # 三目运算符,用法:x
>y?x:y 若x>y,则返回x,否则,返回y|| 逻辑或
&& 逻辑与
~ ~! 匹配正则表达式不匹配正则表达式
<<=>>=!=== 关系运算符
空格 连接
+- 加减
*/% 乘除求余
^ 求幂
++-- 自加自减
$ 引用字段
in 数组成员
+-! 一元加、减和逻辑非
Linux常用命令之awk http://www.linuxidc.com/Linux/2016-09/135046.htm
Linux系统之文本格式化工具awk http://www.linuxidc.com/Linux/2016-02/128150.htm
AWK简介及使用实例 http://www.linuxidc.com/Linux/2013-12/93519.htm
Linux awk文本分析工具 http://www.linuxidc.com/Linux/2015-12/126217.htm
Linux文本处理工具之awk http://www.linuxidc.com/Linux/2015-01/111437.htm
如何在Linux中使用awk命令 http://www.linuxidc.com/Linux/2014-10/107542.htm
文本分析工具-awk http://www.linuxidc.com/Linux/2014-12/110939.htm
AWK入门基础教程 http://www.linuxidc.com/Linux/2016-12/138138.htm
使用awk格式化输出文本 http://www.linuxidc.com/Linux/2016-04/130193.htm
本文永久更新链接地址:http://www.linuxidc.com/Linux/2017-01/139369.htm