AWK综述
awk 适合于文本处理和报表生成。
1 .AWK调用
调用awk有三种方法(与sed类似):
1)在Shell命令行输入命令调用awk:awk [-F 域分隔符] ‘awk程序段’输入文件
2)将awk程序段插入脚本文件后,然后通过awk命令调用它:awk -f awk脚本文件输入文件【脚本文件的首行不以#!/bin/awk –f开头】
3)将awk命令插入脚本文件后,设置该脚本文件为可执行,然后直接执行该脚本文件,格式为:
./awk脚本文件输入文件 【脚本文件的首行以#!/bin/awk –f开头】
1.1 以下以调用方式1为例展示AWK命令用法:
如执行$ awk '{ print }' /etc/passwd,会见到 /etc/passwd 文件的内容出现在眼前。调用 awk 时,指定 /etc/passwd 作为输入文件。执行 awk 时,它依次对 /etc/passwd 中的每一行执行 print 命令。所有输出都发送到 stdout,所得到的结果与与执行catting /etc/passwd完全相同。
另一个相同作用的 awk 示例:$ awk '{ print $0 }' /etc/passwd
在 awk 中,$0 变量表示整个当前行,所以 print 和 print $0 的作用完全一样。
还可以创建一个 awk 程序,让它输出与输入数据完全无关的数据。以下是一个示例:$ awk '{ print "" }' /etc/passwd
只要将 "" 字符串传递给 print 命令,它就会打印空白行。如果测试该脚本,将会发现对于 /etc/passwd 文件中的每一行,awk 都输出一个空白行。再次说明, awk 对输入文件中的每一行都执行这个脚本。
awk 非常善于处理分成多个逻辑字段的文本,可以毫不费力地引用 awk 脚本中每个独立的字段。以下脚本将打印出系统上所有用户帐户的列表:
$ awk -F":" '{ print $1 }' /etc/passwd
上例中,在调用 awk 时,使用 -F 选项来指定 ":" 作为字段分隔符。awk 处理 print $1 命令时,它会打印出在输入文件中每一行中出现的第一个字段。
同理,外部文件的输入大抵如此。
将脚本作为命令行自变量传递给 awk 对于小的单行程序来说是非常简单的,而对于多行程序,它就比较复杂。在外部文件中撰写脚本。然后可以向 awk 传递 -f 选项,以向它提供此脚本文件:
$ awk -f myscript.awk myfile.in
将脚本放入文本文件还可以使用附加 awk 功能。例如,这个多行脚本与前面的单行脚本的作用相同,它们都打印出 /etc/passwd 中每一行的第一个字段:
BEGIN {
FS=":"
}
{ print $1 }
这两个方法的差别在于如何设置字段分隔符。在这个脚本中,字段分隔符在代码自身中指定(通过设置 FS 变量),而在前一个示例中,通过在命令行上向 awk 传递 -F":" 选项来设置 FS。通常,最好在脚本自身中设置字段分隔符,只是因为这表示您可以少输入一个命令行自变量。
1.2 BEGIN 和 END 块
上例中提及了BEGIN和END块。下面来简述一下该部分内容。
通常,对于每个输入行,awk 都会执行每个脚本代码块一次。然而,在许多编程情况中,可能需要在 awk 开始处理输入文件中的文本之前执行初始化代码。对于这种情况,awk 允许定义一个 BEGIN 块。
与BEGIN块对应,awk 还提供了另一个特殊块,叫作 END 块。awk 在处理了输入文件中的所有行之后执行这个块。通常,END 块用于执行最终计算或打印应该出现在输出流结尾的摘要信息。
1.3 规则表达式和块
awk 允许使用规则表达式,根据规则表达式是否匹配当前行来选择执行独立代码块。以下示例脚本只输出包含字符序列 foo 的那些行:/foo/ { print }
以下脚本将只打印包含浮点数的行:/[0-9]+\.[0-9]*/ { print }。
1.4 AWK内部变量解析
awk认为输入文件是结构化的,awk将每个输入文件行定义为记录,行中的每个字符串定义为域,域之间用空格、Tab键或其他符号进行分割,分割域的符号就叫分隔符。
awk提供的内建变量(变量名全部大写)如下:
ARGC:命令行参数的数量。
ARGIND :命令行正在处理的当前文件的AGV的索引。
ARGV :命令行参数数组。
CONVFMT :转换数字格式。
ENVIRON :从shell中传递来的包含当前环境变量的数组。
ERRNO :当使用close函数或者通过getline函数读取的时候,发生的重新定向错误的描述信息就保存在这个变量中。
FIELDWIDTHS :在对记录进行固定域宽的分割时,可以替代FS的分隔符的列表。
FILENAME :当前的输入文件名。
FNR :当前文件的记录号。
FS :输入分隔符,默认是空格。
IGNORECASE:在正则表达式和字符串操作中关闭大小写敏感。
NF :当前文件域的数量。
NR :当前文件记录数。
OFMT :数字输出格式。
OFS:输出域分隔符。
ORS:输出记录分隔符。
RLENGTH :通过match函数匹配的字符串的长度。
RS :输入记录分隔符。
RSTART :通过match函数匹配的字符串的偏移量。
SUBSEP :下标分隔符。
先来看几个简单的小例子:
BEGIN {
FS="\n"
RS=""
}
在上面这段代码中,将 FS 设置成 "\n" 告诉 awk 每个字段都占据一行。通过将 RS 设置成 "",还会告诉 awk 每个地址记录都由空白行分隔。
BEGIN {
FS="\n"
RS=""
OFS=", "
}
{
print $1, $2, $3
}
缺省情况下的输出结果,OFS 被设置成 " ",单个空格。不过,我们可以方便地重新定义 OFS,这样 awk 将插入我们中意的字段分隔符。它使用 OFS 来输出那些中间的 ", " 字符串
awk 还有一个特殊变量 ORS,全称是“输出记录分隔符”。通过设置缺省为换行 ("\n") 的 OFS,我们可以控制在 print 语句结尾自动打印的字符。缺省 ORS 值会使 awk 在新行中输出每个新的 print 语句。如果想使输出的间隔翻倍,可以将 ORS 设置成 "\n\n"。或者,如果想要用单个空格分隔记录(而不换行),将 ORS 设置成 ""。
1.5 AWK重定向
AWK的重定向与Linux/Unix重定向基本一致。
在动作语句中使用shell通用的重定向输出符号">"就可以完成awk的重定向操作,当使用>的时候,原有文件将被清空,同时文件持续打开,直到文件被明确的关闭或者awk程序终止。来自后面的打印语句的输出会追加到前面内容的后面。符号">>"用来打开一个文件但是不清空原有文件的内容,重定向的输出只是被追加到这个文件的末尾。
/> awk '$4 >= 70 {print $1,$2 > "passing_file"}' filename #注意文件名需要用双引号括起来。
awk中对于输入重定向是通过getline函数来完成的。getline函数的作用是从标准输入、管道或者当前正在处理的文件之外的其他输入文件获得输入。他负责从输入获得下一行的内容,并给NF、NR和FNR等内建变量赋值。如果得到一个记录,getline就返回1,如果达到文件末尾就返回0。如果出现错误,如打开文件失败,就返回-1。
/> awk 'BEGIN { "date" | getline d; print d}'
Tue Nov 15 15:31:42 CST 2011
上例中的BEGIN动作模块中,先执行shell命令date,并通过管道输出给getline,然后再把输出赋值给自定义变量d并打印输出它。
/> awk 'BEGIN { "date" | getline d; split(d,mon); print mon[2]}'
Nov
上例中date命令通过管道输出给getline并赋值给d变量,再通过内置函数split将d拆分为mon数组,最后print出mon数组的第二个元素。
/> awk 'BEGIN { while("ls" | getline) print}'
employees
employees2
testfile
命令ls的输出传递给getline作为输入,循环的每个反复,getline都从ls的结果中读取一行输入,并把他打印到屏幕。
/> awk 'BEGIN { printf "What is your name? "; \
getline name < "/dev/tty"}\
$1 ~ name {print "Found" name " on line ", NR "."}\
END {print "See ya, " name "."}' employees2
What is your name? Mary
Found Mary on line 2.
See ya, Mary.
上例先是打印出BEGIN块中的"What is your name? ",然后等待用户从/dev/tty输入,并将读入的数据赋值给name变量,之后再从输入文件中读取记录,并找到匹配输入变量的记录并打印出来,最后在END块中输出结尾信息。
/> awk 'BEGIN { while(getline < "/etc/passwd" > 0) lc++; print lc}'
32
awk将逐行读取/etc/passwd文件中的内容,在达到文件末尾之前,计数器lc一直自增1,当到了末尾后打印lc的值。lc的值为/etc/passwd文件的行数。
由于awk中同时打开的管道只有一个,那么在打开下一个管道之前必须关闭它,管道符号右边可以通过可以通过双引号关闭管道。如果不关闭,它将始终保持打开状态,直到awk退出。
/> awk {print $1,$2,$3 | "sort -4 +1 -2 +0 -1"} END {close("sort -4 +1 -2 +0 -1") } filename
上例中END模块中的close显示关闭了sort的管道,需要注意的是close中关闭的命令必须和当初打开时的完全匹配,否则END模块产生的输出会和以前的输出一起被sort分类。
相关推荐
### sed命令和awk编程教程知识点概述 #### 一、sed命令基本概念与使用方法 - **sed命令简介**: - `sed` 是一个非交互式的流编辑器(Stream Editor),主要用于自动化文本处理任务,尤其适合处理大型文件或者复杂的...
描述:“高效awk编程,高清文字版” 这里的描述向我们传达了这本书的目的和特色。首先,“高效”强调了效率和优化,意味着书中将教你如何编写出高效能的awk脚本。其次,“高清文字版”可能意味着这本书的电子版格式...
AWK是一种非常实用的编程语言,它在文本处理和数据分析方面表现出色。它的特点是编写程序非常简单,即便是只有一两行的程序也能完成复杂的任务。AWK非常适合那些需要快速解决特定数据处理问题的场景。 ### AWK程序...
在shell编程中,awk的灵活性和强大功能使其成为不可或缺的一部分。 1. **基本语法** awk的工作原理基于模式匹配和执行相应的动作。基本语法结构是 `awk 'pattern {action}' file`。pattern是匹配条件,action是...
1. **打印功能**:`print`是awk中最基本的输出函数,它可以打印一行或特定字段。例如,`$awk '{print $0}' /etc/passwd`会打印出`/etc/passwd`文件的每一行,其中`$0`代表当前处理的整行。 2. **变量`$0`与`FS`**:...
总结来说,awk 是一种强大的文本处理工具,通过模式匹配和自定义操作,可以高效地处理和解析文本数据。熟练掌握 awk,能帮助我们在处理大量文本信息时提高效率,尤其在系统管理和数据分析领域有着广泛的应用。
在处理文本时,awk允许自定义字段变量,以实现对字段的引用和操作,如`$1`、`$2`分别代表第一、第二字段。 ### sed sed(stream editor)是一个流编辑器,用于对文本进行过滤和转换。sed一次处理一行,可以执行...
1. **awk简介**:介绍awk编程语言的历史背景、发展过程以及与其他脚本语言的区别。 2. **基本语法和结构**:讲解awk程序的基本结构、变量定义、数据类型、运算符等基础知识。 3. **输入/输出处理**:详细说明如何...
### Linux Shell 编程之 Awk 用法详解 在Linux环境下,Awk是一种强大的文本处理工具,用于处理结构化的数据。Awk不仅能够执行基本的打印操作,还能进行复杂的模式匹配、数据筛选和数学运算,是Linux系统管理员和...
根据您提供的文件内容,这里总结了关于awk的一些知识点。 ### 1. Awk概述 Awk是一种编程语言,用于处理文本模式和报告生成。它主要用于Linux操作系统,并广泛应用于UNIX Shell编程中。Awk按照记录和字段的方式来...
### AWK编程语言知识点概述 #### 一、AWK编程语言简介 - **起源与开发者**:AWK编程语言最初由Alfred Aho、Brian Kernighan和Peter Weinberger于1977年开发。 - **特点**:AWK是一种模式匹配语言,用于编写...
2. **简单易用**:相较于C语言等编程语言,AWK的语法更为简洁,使得开发过程更加高效。AWK提供了从简单的命令行工具到复杂的程序设计语言的解决方案,用户可以根据问题的复杂程度选择合适的工具。 3. **易于获取**...
Linux中的`awk`是一个强大的文本分析工具...总结,`awk`是Linux文本处理的重要工具,其灵活性和强大的功能使其在数据分析、日志分析等领域有着广泛的应用。通过深入学习和实践,我们可以充分利用`awk`来提高工作效率。