awk是一种编程语言,gawk是目前最新的版本,当前的Linux版本用的都是gawk,利用gawk可以实现数据查找、抽取文件中数据、创建管道流命令等功能,awk实际是/bin/gawk的链接。
4.3.1 awk编程模型
awk程序由一个主输入循环main input loop维持,主输入循环反复执行,直到终止条件被触发,主输入循环自动依次读取输入文件行,以供处理,而处理文件行的动作是由程序员添加的。
awk还定义了两个特殊的字段:BEGIN和END,BEGIN用于在主输入循环之前执行,即在未读取输入文件之前执行,END则相反,用于在主输入循环之后执行,即在读取输入文件行完毕后执行。
4.3.2 awk调用方法
跟sed类似,也有三种方式:
① 在shell命令行直接输入命令调用,格式为:
awk [-F 域分隔符] 'awk程序段' 输入文件
② 将awk程序段插入脚本文件,然后通过awk命令调用它,格式为:
awk -f awk脚本文件 输入文件
③ 将sed命令插入脚本文件后,将该文件变成可执行,然后直接执行,不过需要一#!/bin/awk -f 开头
./awk脚本文件 输入文件
4.4.1 awk模式匹配
# awk '/^$/{print "this is a blank line."}' input --> 打印空白行,遇到空白行就打印一句话
第三种调用方式,先写个src.awk脚本文件:
#!/bin/awk -f /^$/{print "this is a blank line."}
然后chmod u+x src.awk,然后./src.awk input即可
4.4.2 记录和域
awk将每个输入文件行定义为记录,行中每个字符串定义为域,域之间用空格、Tab键或其他符号进行分割,称之为分隔符。
$1表示第一个域,$2表示第二个域以此类推。注:$0表示所有的域
使用 -F 选项指定分隔符:
# awk -F "\t" '{print $3}' test.txt
还可以通过设置FS的值改变分隔符:
# awk 'BEGIN {FS=","} {print $1}' test.txt
# awk 'BEGIN {FS="\t+"} {print $1}' test.txt --> 利用正则表达式设置分隔符
4.4.3 awk 关系和布尔运算符
运算符 | 意义 |
< | 小于 |
> | 大于 |
<= | 小于等于 |
>= | 大于等于 |
== | 等于 |
!= | 不等于 |
~ | 匹配正则表达式 |
!~ | 不匹配正则表达式 |
使用正则表达式~符号例子
# awk 'BEGIN {FS=":"} $1~/root/' /etc/passwd --> 在/etc/passwd文件中第一个域匹配root的
# awk 'BEGIN {FS=":"} $0~/root/' /etc/passwd --> 全部域匹配root的
# awk 'BEGIN {FS=":"} $0!~/nologin/' /etc/passwd --> 全部域不匹配nologin的
awk的条件语句示例
# awk 'BEGIN {FS=":"} {if($3<$4) print $0}' /etc/passwd
# awk 'BEGIN {FS=":"} {if($3==10 || $4==10) print $0}' /etc/passwd
# awk 'BEGIN {FS=":";count=0} {if($3>99) count++} END {print count}' /etc/passwd --> 列出系统中UID大于99的账号数量
4.4.4 表达式
+ - * / %(模) ^或**(乘方) ++x x++
# awk '/^$/ {print x+=1}' input
一个计算平均值的awk脚本:
#!/bin/awk -f BEGIN {FS=","} { total=$3+$4+$5 avg=total/3 print "result:" + avg }
4.4.5 awk系统变量:
变量名 | 意义 |
$n | 当前记录第 n个域,域间用FS分隔 |
$0 | 记录的所有域 |
ARGC | 命令行参数的数量 |
ARGIND | 命令行中当前文件的位置(以0开始标号) |
ARGV | 命令行参数数组 |
CONVFMT | 数字转换格式 |
ENVIRON | 环境变量关联数组 |
ERRNO | 最后一个系统错误描述 |
FIELDWIDTHS | 字段宽度列表,空格键分割 |
FILENAME | 当前文件名 |
FNR | 浏览文件的记录数 |
FS | 字段分隔符,默认是空格 |
IGNORECASE | 布尔变量,如果为真,忽略大小写 |
NF | 当前记录中的域数量 |
NR | 当前记录数,从1开始,表示当前是第几条记录 |
OFMT | 数字的输出格式 |
OFS | 输出域分隔符,默认是空格键 |
ORS |
输出记录分隔符,默认是\n |
RLENGTH | 由match函数所匹配的字符串长度 |
RS | 记录分隔符,默认是\n |
RSTART | 由match函数匹配的字符串的第1个位置 |
SUBSEP | 数组下标分隔符,默认是\034 |
另外还有个RT:
RT就是当RS为正则表达式时的匹配到的每个记录的分割符的内容即为RT变量表示,用到RS的时候一般可以用RT作为每次匹配的分割符的变量的值,靠,这么解释你还不清楚就去面壁去吧。^_^
# echo "111 222a333 444b555 666"|awk 'BEGIN{RS="[a-z]+"}{print $1,RS,RT}'
当RT是利用RS匹配出来的内容。如果RS是某个固定的值时,RT就是RS的内容
示例:打印19000行至20000行
# awk '{if(NR>= 19900 && NR<=20000) print $0}' /data/log/resin/resin.log
判断log日志中通过日期的比较来打印:
# awk -F, 'BEGIN{now=systime();aa=strftime("%Y-%m-%d %H:%M:%S", now)}{if ($2 > aa) print $0}' input
# awk -F, 'BEGIN{now=mktime("2013 10 05 12 12 12 333");aa=strftime("%Y-%m-%d %H:%M:%S", now)}{if ($2 > aa) print $0}' input
4.4.6 格式化输出
awk使用类似于C语言的printf函数格式化输出
基本语法是:printf (格式控制符, 参数)
# awk 'BEGIN {FS=","} {printf("%-15s\t%s\n",$1,$3)} ' input.txt
下面这个例子没有输入文件,直接打印一个数字,很神奇吧。
# awk 'BEGIN {printf("%-10.3f\n", 2009.12345)}'
4.4.7 内置字符串函数
字符串替换、查找、分割功能,有很多内置函数,let me see see:
函数名 | 意义 |
gsub(r,s) | 在整个$0中用s替换r |
gsub(r,s,t) | 在t中用s替换r,t可以是字符串也可以是域 |
index(s,t) | 返回s中第一个字符串t的位置,从1开始 |
length(s) | 返回s的长度 |
match(s,t) | 测试s是否包含匹配t的字符串,t可以是正则式 |
split(r,s,t) | 在t上利用分割正则式r分割成序列s |
sub(r,s,t) | 将t中第一次出现的r替换成s |
substr(r,s) | 返回字符串r中从s开始的后缀部分 |
substr(r,s,t) | 返回字符串r中从s开始长度为t的后缀部分 |
解释下
gsub函数执行字符串替换功能,它将第一个字符串替换成第二个字符串。gsub函数有两种形式,第一种形式作用于全部域$0,也就是gsub(r,s)。第二种形式作用于域t,也就是gsub(r,s,t)
// 第一条命令:替换第1域上的root字符串,注意我的输出的分隔符设定OFS
# awk 'BEGIN {FS=":"; OFS="+"} {gsub(/root/,"haha",$1); print $0}' /etc/passwd
# awk 'BEGIN {FS=":"; OFS="+"} gsub(/root/,"haha",$1) {print $0}' /etc/passwd
上面两行的席位区别,然后输出结果是:第一个命令会输出所有行,第二个只会输出gsub找到的那行,why
// index和length函数的用法
# awk 'BEGIN {print index("google.com", ".com")}'
# awk 'BEGIN {print length("google.com")}'
match(s,t)测试s是否包含正则表达式t字符串,若匹配成功,则返回t的首位置,若不成功,则返回0
# awk 'BEGIN {print match("grade one", /D/)}'
# awk 'BEGIN {IGNORECASE=1; print match("grade one", /D/)}'
// sub(r,s,t) 只是将t中第一次出现的r替换成s
# awk 'BEGIN {str="multiprocessors program"; sub(/pro/, "PRO", str); printf("%s\n", str)}'
// substr两个函数示例:
# awk 'BEGIN {str="multiprocessor programming"; print substr(str,6)}'
# awk 'BEGIN {str="multiprocessor programming"; print substr(str,6,9)}'
4.4.8 向awk脚本传递参数
格式为: awk脚本文件 param1=value1 param2=value2 输入文件
其中param可以是自定义变量,也可以是系统变量
注意:命令行参数不能被BEGIN中的语句访问到
4.4.9 条件语句和循环语句
这个跟C语言语法是一样的,不多做介绍了
# if (x==y) print x
# if (x ~ /[Hh]el?o) print x
while(cond) action
do action while(cond)
for (i=0; i<10; i++) print i
4.4.10 数组
array[index]=value
awk数组无需定义数组类型和大小,赋值后就能使用了,哦也。
1. 关联数组
关联数组其实就是一个Map,实际上awk数组就是一个Map,array[0]=12表示用字符串0为key,12为value
awk所有数组都是关联数组,array[09]跟array[9]完全不一样
基于上述的关联数组的含义,awk定义了一组foreach循环,而且很特殊的,跟java中还不一样:
for (var in array)
print array[var]
实际上var就相当于Map中的key,这样可以理解了吧,^_^
还有个条件表达式,相当于判断Map是否含有这个key值:
if (index in array) print "yes"
2. split函数
终于要到压轴大戏也就是大名鼎鼎的split函数了
split(r,s,t):将字符串r以t为分隔符拆分成字符串数组,存放在s中。 并返回数组s的大小
# awk 'BEGIN {print split("abc/def/ghi",str,"/")}'
# awk 'BEGIN {FS=","} {print split($1,name," ")}' input.txt
再来看一下一个小小脚本:
#!/bin/awk -f BEGIN {FS=","} { split($1,names," "); for (i in names) print name[i] }
3. 数组形式的系统变量
ARGV和ENVIRON两个
ARGC是ARGV数组中元素的个数
# awk -f argv.awk xyz n=99 "Hello World"
结果打印: awk,xyz,n=99,,Hello World
ENVIRON变量存储了Linux系统的环境变量
例如:
awk 'BEGIN {for(i in ENVIRON) print(i" = "ENVIRON[i])}'
4. awk 执行系统命令:
ls -l -c --time-style="+%Y-%m-%d" | awk '{if($6 == "2013-07-01") system("rm -rf " $7)}'
不小心在当前页面新建了很多文件,怎样马上删除呢?就是上面的例子
本人博客已搬家,新地址为:http://www.pycoding.com/
相关推荐
Linux Shell 编程基础教程 本资源为 Linux Shell 编程基础教程,涵盖了 Linux Shell 编程的基础知识,包括语法基本介绍、变量、环境变量、Shell 命令和流程控制等。 一、语法基本介绍 在 Linux Shell 编程中,...
**五、AWK编程** AWK是一种强大的文本分析工具,常用于处理和分析结构化的数据文件。它在每一行数据上运行用户定义的模式匹配和操作,提供了灵活的数据处理能力。 AWK的基本结构包括模式(pattern)和动作(action...
### Linux Shell 编程之 Awk 用法详解 在Linux环境下,Awk是一种强大的文本处理工具,用于处理结构化的数据。Awk不仅能够执行基本的打印操作,还能进行复杂的模式匹配、数据筛选和数学运算,是Linux系统管理员和...
Linux及Linux Shell简介、初识Linux Shell、常用Shell(Bash)命令、Shell命令进阶、Shell编程基础、Shell的条件执行、Bash循环、Shell函数、正则表达式、脚本输入处理、Shell重定向、管道和过滤器、捕获、sed和awk...
Linux 主要shell命令、sed、awk使用详解 Linux 主要shell命令详解 shell 是用户和 Linux 操作系统之间的接口。Linux 中有多种 shell,其中缺省使用的是 Bash。本章讲述了 shell 的工作原理,shell 的种类,shell ...
awk基础入门(4) Unix系列shell程序编写(上) awk基础入门(5) ...Linux的shell编程(三) Linux的shell编程(四) Shell学习笔记 一 Shell学习笔记 二 Shell学习笔记 三 Shell学习笔记 四 Shell学习笔记 五
总的来说,"AWK编程实例指南.rar"提供的资源对于想学习或提升AWK编程能力的人来说非常有价值。通过阅读和实践其中的实例,不仅可以理解AWK的基础知识,还能学习如何在实际项目中有效地应用它。无论是数据处理、日志...
《跟老男孩学Linux运维:Shell编程实战》这本书主要涵盖了Linux运维中的一个重要技能——Shell脚本编程。在Linux系统管理中,Shell脚本是自动化任务处理、系统维护和程序开发的重要工具。以下将深入探讨书中的核心...
此外,了解并熟练使用常见的Linux工具,如grep、awk、sed等,将使你的Shell编程能力更上一层楼。 总的来说,Linux Shell编程是Linux系统管理与自动化的重要手段,它不仅提升了工作效率,也为解决问题提供了灵活的...
但根据文件信息中的标题和描述,可以推断出本书内容涉及Linux Shell编程的基础知识和技能提升。下面将基于Linux Shell编程这一主题,详细说明相关知识点。 Linux Shell编程是学习Linux系统管理和自动化脚本的重要...
Linux Shell编程是Linux系统中非常重要的一个环节,它允许用户通过命令行接口执行各种操作,进行自动化任务处理。shell作为用户与操作系统之间的桥梁,提供了一系列强大的功能,包括脚本编写、文件管理、进程控制等...
Linux Shell编程是Linux系统管理与自动化任务的核心技术之一。Shell脚本可以理解为Linux环境下的批处理程序,它允许用户通过编写脚本来执行一系列命令,从而实现自动化操作,提高工作效率。这本书《Linux Shell编程...
awk作为sehll脚本开发的三大利器之一,该文档对awk语法做了详细的介绍病附带示例,唯一不足之处在于没有形成规范的doc文档
Linux Shell编程实训是一份详实的教程,涵盖了从基础到高级的Shell编程知识,适合对Linux系统管理和自动化脚本感兴趣的初学者和进阶者。该实训主要包括以下项目: 1. **初识Linux Shell**:这部分内容旨在建立开发...
在IT领域,Shell和Awk是两种非常强大的命令行工具,尤其在文本处理和数据分析方面。本教程将深入探讨这两个工具的结合使用,提供一系列实用的实例,帮助你提升工作效率。 **Shell** 是Unix和Linux操作系统中的命令...
13Linux下Shell编程之While case演练 14Linux下Shell编程之While case演练 15Shell编程之函数及脚本案例讲解 16Shell编程之函数及脚本案例讲解 17Linux下Shell编程FIND、SED命令实战 18Linux下Shell编程FIND、SED...
《Unix与Linux Shell编程指南》是一本专注于操作系统交互和自动化任务执行的实用手册。Shell编程在Linux和Unix环境中扮演着核心角色,它提供了一种高效的方式来进行系统管理、任务自动化以及用户界面定制。以下是...