`

《Linux Shell》之三:awk编程

阅读更多

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/

分享到:
评论

相关推荐

    LinuxShell编程基础教程.pdf

    Linux Shell 编程基础教程 本资源为 Linux Shell 编程基础教程,涵盖了 Linux Shell 编程的基础知识,包括语法基本介绍、变量、环境变量、Shell 命令和流程控制等。 一、语法基本介绍 在 Linux Shell 编程中,...

    shell、awk编程教材

    **五、AWK编程** AWK是一种强大的文本分析工具,常用于处理和分析结构化的数据文件。它在每一行数据上运行用户定义的模式匹配和操作,提供了灵活的数据处理能力。 AWK的基本结构包括模式(pattern)和动作(action...

    linux shell 编程之 awk用法

    ### Linux Shell 编程之 Awk 用法详解 在Linux环境下,Awk是一种强大的文本处理工具,用于处理结构化的数据。Awk不仅能够执行基本的打印操作,还能进行复杂的模式匹配、数据筛选和数学运算,是Linux系统管理员和...

    Linux主要shell命令、sed、awk使用详解

    Linux 主要shell命令、sed、awk使用详解 Linux 主要shell命令详解 shell 是用户和 Linux 操作系统之间的接口。Linux 中有多种 shell,其中缺省使用的是 Bash。本章讲述了 shell 的工作原理,shell 的种类,shell ...

    Linux+Shell命令行及脚本编程实例详解-刘艳涛.mobi kindle版

    Linux及Linux Shell简介、初识Linux Shell、常用Shell(Bash)命令、Shell命令进阶、Shell编程基础、Shell的条件执行、Bash循环、Shell函数、正则表达式、脚本输入处理、Shell重定向、管道和过滤器、捕获、sed和awk...

    shell编程教程.chm

    awk基础入门(4) Unix系列shell程序编写(上) awk基础入门(5) ...Linux的shell编程(三) Linux的shell编程(四) Shell学习笔记 一 Shell学习笔记 二 Shell学习笔记 三 Shell学习笔记 四 Shell学习笔记 五

    AWK编程实例指南.rar_AWK ns2_awk_awk unix.shell_awk编程实例

    总的来说,"AWK编程实例指南.rar"提供的资源对于想学习或提升AWK编程能力的人来说非常有价值。通过阅读和实践其中的实例,不仅可以理解AWK的基础知识,还能学习如何在实际项目中有效地应用它。无论是数据处理、日志...

    刘艳涛版LinuxShell命令行及脚本编程实例详解(含mobi阅读器)

    《刘艳涛版Linux Shell命令行及脚本编程实例详解》是一本专为Linux Shell编程初学者和进阶者设计的教程。这本书深入浅出地介绍了Linux操作系统中的Shell命令行和脚本编程技术,旨在帮助读者掌握在终端环境中高效工作...

    跟老男孩学Linux运维:Shell编程实战

    《跟老男孩学Linux运维:Shell编程实战》这本书主要涵盖了Linux运维中的一个重要技能——Shell脚本编程。在Linux系统管理中,Shell脚本是自动化任务处理、系统维护和程序开发的重要工具。以下将深入探讨书中的核心...

    linux shell 编程1

    此外,了解并熟练使用常见的Linux工具,如grep、awk、sed等,将使你的Shell编程能力更上一层楼。 总的来说,Linux Shell编程是Linux系统管理与自动化的重要手段,它不仅提升了工作效率,也为解决问题提供了灵活的...

    LINUX SHELL编程从初学到精通

    但根据文件信息中的标题和描述,可以推断出本书内容涉及Linux Shell编程的基础知识和技能提升。下面将基于Linux Shell编程这一主题,详细说明相关知识点。 Linux Shell编程是学习Linux系统管理和自动化脚本的重要...

    Linux shell编程

    Linux Shell编程是Linux系统中非常重要的一个环节,它允许用户通过命令行接口执行各种操作,进行自动化任务处理。shell作为用户与操作系统之间的桥梁,提供了一系列强大的功能,包括脚本编写、文件管理、进程控制等...

    linux Shell 编程实例书一本

    Linux Shell编程是Linux系统管理与自动化任务的核心技术之一。Shell脚本可以理解为Linux环境下的批处理程序,它允许用户通过编写脚本来执行一系列命令,从而实现自动化操作,提高工作效率。这本书《Linux Shell编程...

    linux shell awk 编程

    awk作为sehll脚本开发的三大利器之一,该文档对awk语法做了详细的介绍病附带示例,唯一不足之处在于没有形成规范的doc文档

    新版Linux Shell编程实训(全)20170518.docx

    Linux Shell编程实训是一份详实的教程,涵盖了从基础到高级的Shell编程知识,适合对Linux系统管理和自动化脚本感兴趣的初学者和进阶者。该实训主要包括以下项目: 1. **初识Linux Shell**:这部分内容旨在建立开发...

    shell awk实用实例教程

    在IT领域,Shell和Awk是两种非常强大的命令行工具,尤其在文本处理和数据分析方面。本教程将深入探讨这两个工具的结合使用,提供一系列实用的实例,帮助你提升工作效率。 **Shell** 是Unix和Linux操作系统中的命令...

    Shell编程高级进阶系列视频.zip

    13Linux下Shell编程之While case演练 14Linux下Shell编程之While case演练 15Shell编程之函数及脚本案例讲解 16Shell编程之函数及脚本案例讲解 17Linux下Shell编程FIND、SED命令实战 18Linux下Shell编程FIND、SED...

Global site tag (gtag.js) - Google Analytics