`
xiangzi21
  • 浏览: 30092 次
  • 性别: Icon_minigender_1
  • 来自: 大连
社区版块
存档分类
最新评论

sed与awk菜鸟的笔记--第七章 编写awk脚本

阅读更多

第七章 编写awk脚本


规则:
awk脚本分三部分 (BEGIN,END必须大写)
1.BEGIN段:主循环处理前(不管主循环有没有数据)
2.主循环段:主循环处理(文件行数)
3.END段:主循环处理后(不管主循环有没有数据)


模式匹配:
当awk读入输入行时,只有与模式匹配才能执行指定操作,如果没有指定操作,匹配的行会被打印出来.
$ awk '/^$/ {print "this is a blank line"}' file #如果file匹配到空行即打印"this is a blank line"(即文件有几个空行便打印几句"this...").
$ awk '/AA/ ' file     #如果file匹配到"AA"即打印匹配行的内容(因为没指定命令).


#以下脚本判断是整数,字符串还是空行.(注意:print打印的不能用单引号)
$ cat test.awk
/[0-9]+/ {print "integer"}
/[a-zA-Z]+/ {print "string"}
/^$/ {print "blank"}


#脚本执行效果如下,脚本判断输入的是int还是string或空.当输入"4r4"的时候,一行匹配多条规则.只输入回车的时候显示"blank".
$ awk -f test.awk
43  #输入
integer
t  #输入
string
  #输入
blank
4r4  #输入
integer
string


程序脚本注释:
以"#"开始,换行符结束.和sed不同,awk可以在程序任何地方添加注释.
在命令行中运行awk程序,则不能用单引号,否则会被shell解析.(将awk写成文件脚本貌似也不可以).


记录和字段:
对于每一行来说,可将行分为多个字段.默认以空格或制表符来作为分隔符.
#此记录即为3个字段,以空格或制表符分隔
$ cat file
A B C


字段的引用和分离:
用$来指定字段.在该操作符后面跟数字或变量,用于标识符的位置.
#以下print以逗号做分隔符,输出时默认为空格(以后可讲到用OFS设置其他分隔符).若不用逗号则无分隔符.
$ cat file
A B C

$ awk '{print $2,$1,$3}' file
B A C

$ awk '{print $2      $1   $3}' file
BAC


#以下$(ONE+TWO) 等价于$3.可以用任何计算值为整数表达式表示一个字段,而不只是用数字或变量.
$ echo a b c | awk 'BEGIN {ONE = 1;TWO = 2} {print $(ONE+TWO)} '
c


可以在命令行中用-F参数设置分隔符
#以下将制表符设置为分隔符,file中只有一个制表符,所以该制表符前面为$1,后面为$2,$3为空
$ cat file
A B C

$ awk -F'\t' '{print $1}' file
A B

$ awk -F'\t' '{print $2}' file
C

$ awk -F'\t' '{print $3}' file


在脚本中指定域分隔符(字段分隔符)是个很好的习惯.指定必须在读取第一个输入行前执行,所以要在BEGIN中执行.
BEGIN {FS=","} #指定逗号为域分隔符(与在命令行中加参数"-F"效果相同,等同于awk -F ',')

$cat game
I,love,this,game!

$cat awk1
BEGIN {FS = ","}
{print $1 "INS   ERT" $3}

$awk -f awk1 game
IINS   ERTthis
 
使用(~)可以测试一个字段的正则表达式,(!~)表示取反
$5 ~ /AA/ {print $0} #将第五列匹配AA的整行打印
$5 !~ /AA/ {print $1} #打印出第五列不匹配AA的行的第一列(即如果改行第五列不匹配AA,那么打印该行的第一列)


字段的划分:完整的问题

可以用正则表达式指定分隔符
FS = "\t" #使用一个制表符作为分隔符
FS = "\t+" #使用一个或多个制表符作为分隔符
FS = "[,:\t]" #在中括号里的三个字符都可以被解释为分隔符

#以下以逗号或冒号为分隔符,将字符串"a,b:cdd:e"分为四个域a b cdd e
$ echo "a,b:cdd:e"|awk -F'[,:]' '{print $1,$2,$3}'
a b cdd


表达式:
可以使用表达式来储存,操作和检索数据,这些操作与在sed中有很大区别.
p170有转义符号
变量有两种类型,数字型和字符串型.变量不需要声明,默认为0或空串.
z = "Hello"  #将字符串"Hello"赋给变量z
z = "Hello" "World" #空格为连接操作符.前面表达含义为:将字符串"HelloWorld"赋给变量z
z = $1   #美元符号($)是引用字段操作.前面表达含义为:将输入的第一个字段赋给变量z

算术表达式
+(加)
-(减)
*(乘)
/(除)
%(取模)
^(取幂)


赋值操作符
++ 变量加一
-- 变量减一
+= 加结果赋给变量(以下略)
-=
*=
/=
%=
^=
**=


#有空行便打印变量x ,
/^$/ {print x += 1} 或/^$/ {print ++x}


#统计空行数,统计最终结果后打印变量
/^$/ {
++x
}
END{
 print x
}


#计算学生平均成绩
$ cat file
Tom 90 85 77
Jerry 99 73 90

$ cat grades.awk
{ total = $2 + $3 + $4
  print $1,total/3
}

$ awk -f grades.awk file
Tom 84
Jerry 87.3333


系统变量:
FS:输入字段分隔符(默认为空格)
OFS:输出字段分隔符(默认为空格)
NF:输入记录的字段个数(每行分别的字段个数),$NF为每输入行的最后一个字段
RS:输入行分隔符(默认为一个换行符)
ORS:输出行分隔符(默认为一个换行符)
FILENAME:当前输入文件的名称
FNR:多个输入文件时,表示与当前输入文件相关的当前记录代码.
NR:到目前为止输入的行数,如果写在END里,则为输入多少行

处理多行记录:
下面的例子演示读入一个记录,而记录中每个字段都是单独成一行.
#文件中分别为姓名,性别,年龄,籍贯
#脚本将字段分隔符FS设置为换行符,记录分隔符RS设置为空字符串,并打印第一和最后一个字段.

$ cat message
Tom
male
25
Liaoning


Jerry
male
20
Shandong


$ cat rows.awk
BEGIN{ FS="\n" ;RS="" }
{print $1,$NF}


$ awk -f rows.awk message
Tom Liaoning
Jerry Shandong


#下面是将输出列分隔符OFS设置为换行符,记录分隔符ORS为空行(即需要两个换行符)
$ cat rows.awk
BEGIN{ FS="\n" ;RS="" ;OFS="\n";ORS="\n\n" }
{print $1,$NF}


$ awk -f rows.awk message
Tom
Liaoning


Jerry
Shandong

p179支票结算示例的简单脚本,这里不举例了.


关系操作符和布尔操作符
<,>,<=,>=,==,!=,~(匹配),!~(不匹配)

NF==6 {print $1,$6} #只有具有六个字段的记录才被打印,并打印出第一和第六个字段

正则表达式可以用变量来提供,这样使代码更通用.


布尔操作符
&&,||,!
&&的优先级高于||


格式化打印
printf(format_expression[,argument]) :printf与C语言中的类似.
其中圆括号是可选的.format_expression是描述格式的表达式,通常为引号括起的字符常量形式.[,argument]是一个参数列表,在格式说明前有个百分号

常用说明符:
c:ASCⅡ字符
d:十进制整数
f:浮点格式
g:e或f的转换形式,长度最短,末尾的0被去掉
s:字符串
u:无符号十进制
%:字面字符%


#下面示例输出十进制的$5,然后是制表符,然后是字符串$9,然后是换行符.
#当使用printf时,必须提供换行符,否则永远不会换行.对每个格式必须提供一个相应的参数.
printf("%d\t%s\n",$5,$9)

printf可以规定输出域可宽度和对齐方式.一个表达式由3个可选的修饰符组成,跟在%后面,并在格式说明符之前.
%-width.precision format-specifier
width是宽度,默认为右对齐,必须指定"-"来设置左对齐.
"%-20s"的意思是左对齐的一个域,长度为20个字符的字符串.不够则用空格补.如果大于20则都输出.
precision修饰符用于十进制或浮点数时,用于控制小数点右边的数字位数.对于字符串型,则用于控制打印字符的最大数量.
数值的默认precision值为"%.6g"
可以通过print或pringf参数列表的值动态指定宽度width和精度precision,通过用星号代替实际的值来实现该功能.
#下例中宽度为5,精度为3,要打印的值来至myvar
printf("%*.*g\n",5,3,myvar)
$ echo a |awk '{printf("%*.*g\n",5,3,4000)}'
4e+03
$ echo a |awk '{printf("%*.*g\n",5,3,400)}'
  400


向脚本传递参数
awk 'script' var-value inputfile
在命令行上,参数放在脚本的后面,输入文件的前面
参数每一项都作为单一参数来解析,所以等号两边不能有空格.
#以下例子为脚本scriptfile传递两个参数.
$ awk -f scriptfile high=100 low=100 datafile

#如果将awk脚本写入shell脚本,则以上脚本方法如下
$ cat awk.sh
awk -f scriptfile "high=$1" "low=$2" datafile

#$1和$2分别为执行shell脚本时的输入参数,以上脚本执行方法如下
$ sh awk.sh 100 100

环境变量的输出结果也可以作为变量值传递
awk '{...}' name=$HOSTNAME file  #将主机名当做参数传给脚本
awk '{...}' dir=`pwd` file  #将当前目录作为参数传给脚本

#也可以使用命令行参数定义系统变量(就不用在HEAD里定义了),下面执行结果相同,但最好用单引号括起来.当记录分隔符中要设置空格时,就必须要用单引号了.
$ awk '{print NR,$0}' OFS='.' file
$ awk '{print NR,$0}' OFS=. file

命令行参数的一个重要限制是它们在BEGIN过程中是不可用的.也就是说BEGIN执行后它们才会被读入.
#下面为命令行输入,执行顺序为:
1.执行BEGIN的操作 (由于变量n是空,则打印空行)
2.读入第一个参数 n=1
3.读入第二个参数 file1
4.对file1逐行执行脚本
5.读入第三个参数n=2
6.对file2逐行执行脚本
如果file1有10行,file2有5行,那么下面命令执行后的结果应该为:第一行为空行,然后下面10行"one",再下面是5行"two"


$ awk 'BEGIN {print n}
{
if (n==1) print "one"
if (n==2) print "two"
}' n=1 file1 n=2 file2

one
two

如果想在BEGIN之前设置输入参数,则要用-v参数
$ awk -v n=1 'BEGIN {print n}' file #
$ awk 'BEGIN {print n}' file n=1

 

 

 

0
0
分享到:
评论

相关推荐

    sed and awk 101 hacks.pdf

    Sed和Awk是UNIX和Linux系统中极为重要的流编辑器和文本处理工具,它们能够通过简单的命令或脚本高效处理文本文件,实现复杂的文本转换和报告生成。接下来,我们将根据提供的文件内容详细地说明Sed和Awk的关键知识点...

    Sed与Awk (中文版)

    本书是sed与awk的第二版,由O'Reilly & Associates出版,并授权给机械工业出版社在中国发行。书中提及的ISBN7-111-11527-9为本书的标识。第一版由Dougherty和Robbins著,张旭东等人翻译,机械工业出版社出版于2003年...

    Vim-101-hacks、Sed-and-Awk-101-Hacks、Linux-101-hacks 英文版(高清)PDF

    "Sed-and-Awk-101-Hacks"可能包含如何使用基本的sed命令,如替换、删除、插入行,以及使用地址范围进行特定操作。此外,还可能涉及正则表达式在sed中的应用,如查找和替换模式,以及使用sed进行批量文本编辑。 3. ...

    SED与AWK 高清第三版

    《SED与AWK 高清第三版》是一本专注于Linux系统中强大文本处理工具sed和awk的教程。在Linux环境中,sed和awk是不可或缺的工具,它们能够高效地处理大量文本数据,进行搜索、替换、格式化等操作,极大地提高了运维...

    Sed与awk_中英文高清版

    《Sed与Awk》是IT领域中关于文本处理的经典之作,主要讲解了两种强大的命令行工具:Sed(流编辑器)和Awk(数据处理语言)。这两款工具在Linux和Unix系统中广泛使用,尤其适用于数据提取、转换、报告生成等任务。 ...

    sed-awk-2nd-edition.chm

    The book begins with an overview and a tutorial that demonstrate a progression in functionality from grep to sed to awk. sed and awk share a similar command-line syntax, accepting user instructions in...

    Sed与awk第二版(中文高清版)

    Sed与awk(第二版)这本书作为国外的经典教材,经过翻译后,为中文读者学习这些工具提供了极大的便利。它不仅系统地介绍了sed和awk的使用方法,还通过实例演示了如何编写有效的脚本来处理文本数据。对于那些希望提高...

    sed & awk Pocket Reference-2nd-2002.chm

    English 2nd Edition 2002 chm format Summary of sed & awk

    sed and awk 101 hacks

    第七章介绍了sed的多行命令和循环,这些高级技巧在处理跨多行的数据时非常有用,例如将下一行追加到模式空间(AppendNextLinetoPatternSpace)。 由于文档中存在OCR扫描误差,部分内容可能无法完全通顺。但是根据上...

    Sed与awk第二版(高清版).pdf

    根据提供的文件信息,我们可以从《Sed与awk第二版(高清版).pdf》这一资源中提炼出关于Sed和awk这两个强大的文本处理工具的相关知识点。虽然免责声明部分并未提供具体的技术内容,但我们可以通过书籍的标题、描述及...

    sed与awk(第二版)学习笔记

    sed与awk(第二版)学习笔记

    sed和awk的必备书籍

    包括: 1. sed与awk+第三版(中文高清晰),内容非常全面详细,看了觉得很不错,学习sed和awk的必备书籍。 2. Effective awk Programming, 4th Edition 3. Sed与awk第二版(高清版).pdf

    sed与awk(第二版) - PDF(带目录)

    sed和awk具有相同的命令行语法,以脚本的形式接收用户的命令。因为所有这三个程序都使用UNIX正则表达式,因此书中用一章的篇幅来介绍UNIX的正则表达式语法。 然后,本书介绍如何编写sed脚本。从编写几行简单的脚本...

    sed & awk 第二版 例程 源代码 源码 sed & awk sourcecode

    《sed与awk 第二版 例程 源代码》是一部深入探讨文本处理工具sed和awk的经典著作。这本书的核心在于其丰富的例程和源代码,旨在帮助读者掌握这两个强大的命令行工具的用法。sed(流编辑器)和awk(编程语言)在IT...

    Sed & Awk 2nd Edition

    第七章:开始讲解awk脚本的编写,介绍awk程序的设计和执行流程。 第八章:讲解了在awk脚本中使用条件语句、循环和数组进行更复杂的数据操作。 第九章:探讨awk中的函数,包括内置函数和自定义函数的使用。 第十章...

Global site tag (gtag.js) - Google Analytics