Linux 编辑器(四)--gawk与sed

转载 2012年03月27日 21:52:19

awk是模式扫描和处理语言,又称过滤器,是Linux/Unix下用来操纵数据和产生报告的程序语言。其处理的数据可以来自标准输入、一个或多个文件、或者其他命令的输出。

awk写于1977年,其名称取自其作者姓氏的第一个字母,分别是Alfred V Aho, Peter J. Weinberger和Brian W Kernighan。在1985年的升级版中加入了用户自定义函数、动态正则表达式和处理输入文件等功能,使得awk可以处理大型程序。awk有多个版本,包括旧版awk、nawk(new awk,新版本)、gawk(GNU版本)以及POSIX awk等。很多Linux系统将/bin/awk链接至/bin/gawk。

gawk程序由包含模式和动作的单行或多行文本组成,格式如下:
pattern {action}
模式用来从输入中选取文本行,对于匹配的每行文本,gawk都执行fcwt(action)来处理。

模式用斜杠包装,如:gawk /word/ filename查找所有包含word的行。这里没有指定action,默认为print。

“~”用于测试一行中某段是否匹配模式。一行中可以有多个“段”,各“段”之间由空白符号分隔,如section1 secion2 section3。gwak '$1~/word/' filename在文件中查找第一段匹配word的各行。“!~”用于测试不匹配,如gawk '$2!~/word/' filename。

BEGIN和END是两个独特的模式,分别是在gawk开始处理之前和处理完毕之后要执行的命令。在处理所有输出之前,gawk执行BEGIN模式关联的动作,在处理完之后执行END模式关联的动作。例:gawk 'BEGIN{print "This is the beginning"} {print}' filename。又例: gawk 'BEGIN {print "head"; count=0} {print; count++} END {printf "end: %d", count}' filename。

逗号“,”可以分隔两个模式,作为范围运算符。例:gawk '/abcd/,/efgh/' filename 输出第一行匹配abcd而最后一行匹配efgh的多行。

{print}是默认的动作,不带参数时则输出记录(通常是一行)。参数可以是变量或字符串常量。还可以指定输出到文件,如>(覆盖)、>>(追加)、|(管道)和|&(协进程,双向管道)。例:{print > "somefile"}。多个动作用分号“;”隔开。

“#”开头的程序行表示注释。

gawk不需要声明可以直接使用变量。未赋初始值的变量自动初始化为0或空字符串。除了用户变量(user variable)外,gawk还维护了程序变量(program variable):
$0:当前记录(作为单个变量);
$1-$n:当前记录的字段;
FILENAME:当前输入文件名(null表示标准输入);
FS:输入字段的分隔符;
NF:当前记录的字段数目;
NR:当前记录的记录编号,每处理完一个记录,NR的值就自动加1;
OFS:输出字段分隔符(默认为空格符);
ORS:输出记录分隔符(默认为换行符);
RS:输入记录分隔符(默认为换行符);

除了在程序中初始化变量外,还可以在命令行上用“--assign”或“-v”选项初始化变量。如:awk -v A=1 '{print A}' filename。

gawk把输入文件看作是一个具有一定格式的记录集合,通常一行为一个记录,每个记录被空格分隔成多个字段。-F选项可以指定字段分隔符,如:awk -F: '{print $2}' filename指定分隔符为冒号“:”。而awk -F[:-] ‘{print $2}' filename指定分隔符为冒号“:”或者连字符“-”,即记录1:2-3被视为1、2、3三个字段。输入段分隔符也可以在模式中指定:awk 'BEGIN{FS="[:-]"} {print $2}' filename。

{print $2 $3}会把两个变量合并输出,例如,$2为"a",$3为"b",则前述动作输出“ab”,{print $2,$3}输出"a b"。输出段分隔符可以在BEGIN模式中指定:awk BEGIN{OFS=":"} {print $2}' filename。

gawk支持函数,自带的函数有:
length(str):返回str的字符个数。不带参数则返回当前记录的字符个数。
int(num):返回num的整数部分。
index(str1,str2):str2在str1中的位置,如果不在则返回0。
split(str,arr,del):用del作定界符,将str的元素放置到数组arr[1]...arr[n]中,返回数组元素个数。
sprintf(fmt,args):根据fmt格式化args并返回格式化后的字符串,模仿C编程语言中相应的同名函数。
substr(str,pos,len):返回str中从pos开始长度为len个字符的字符串。
tolower(str):返回str的副本,所有大写字母被转换成小写。
toupper(str):返回str的副本,所有小写字母被转换成大写。

gawk支持关联数组,即array[string]=value。关联数组可以用for来遍历。例:awk '{array[$1]=$2} END{for (elem in array) print elem}' filename。

printf用于格式化输出,语法为:%[-][x[.y]]cov。“-”表示左对齐,“x”表示最小字段宽度,“y”表示数字中小数点右边的位数。“conv”指示数值转换的类型,包括:
d:十进制;
e:指数表示;
f:浮点数字;
g:使用f或e中较短的那个;
o:无符号八进制;
s:字符串;
x:无符号十六进制。

gawk支持关系运算符,包括<、>、<=、>=、==、!=。布尔结果可以用布尔运算符“&&”和“||”来运算。算术运算符支持“+”、“-”、“*”、“/”、“=”、“%”、“++”、“--”、“+=”、“-=”、“*=”、“/=”和“%=”。与C基本一样。

流程控制有if...else,while,for,break和continue。

getline可以用来读取文件中的一行。如awk 'BEGIN {getline myline; print myline}' myfile只输出文件的第一行,可以用循环来控制读取的行数。

awk程序可以写在一个文件里作为脚本文件,再用-f选项指定。例:awk -f myscript filename。

协进程(coprocess)是指与另一个进程并行运行的进程。gawk从版本3.1开始可以通过协进程方式直接与某个后台进程进行信息交换。协进程可用于客户端/服务器环境中(例如构建SQL前端与后端),或者通过网络与远程系统交换数据。例如,下面这个awk脚本:
BEGIN {
    count = 0;
    while (getline myline) {
        print myline |& "./coprocess";
        "./coprocess" |& getline LINE;
        print LINE;
    }
}
它将与同一目录一下的可执行文件coprocess进行协作。下面是coprocess文件的内容:
#!/bin/bash
while read LINE
do
    echo "tommy" $LINE
done
之后运行命令:gawk -f myscript filename,则在filename中的每行前加上“tommy”再输出到标准输出。

在协进程的基础上,gawk还可以通过网络交换数据。gawk可以通过IP网络连接到另一个系统上的某个进程进行信息交换。当用户使用“/inet/”开头的特殊文件名时,gawk将使用网络连接来处理用户的请求。以“inet”开头的特殊文件的格式如下:
/inet/protocol/local-port/remote-host/remote-port
其中“protocol”通常是TCP,也可以是UDP。“local-port”表示本地端口,0表示让gawk自动选择一个端口。“remote- host”表示远端主机的地址,“remote-port”表示远端端口号,可以指定为http或ftp地址。比如下面的代码:
BEGIN {
    server = "/inet/tcp/0/www.google.com/80";
    print "start to connect..";
    print "GET /index.html\r\n" |& server;
    print "request sent."
    while (server |& getline)
        print $0;
    print "done."
}


sed(stream editor,流编辑器)是一个批处理(非交互式)编辑器,可以实现在vi和ex里一样的编辑任务。sed相当小巧,可以利用管道对标准输入/输出的数据进行编辑和组合。sed可以对来自文件或标准输入流进行转换,通常被用作管道中的过滤器。由于sed仅仅对其输入进行一遍扫描,因此比其他交互编辑器(如 ed)更加高效。

sed一次处理一行文本并把处理结果输出送往标准输出设备(屏幕)。sed把当前处理的行存储在模式空间(pattern space)的临时缓冲区中。一旦sed完成对模式空间中行的处理(也就是执行完这一行中的sed命令),模式空间中的行就被送往屏幕(除非命令是删除行或者打印到打印机)。行被处理完成以后,就被移出模式空间,程序接着读入下一行,处理、显示、移出……文件输入的最后一行被处理完成以后,sed结束。通过在临时缓冲区存储每一行,然后在缓冲区中操作该行,保证了原始文件不会被破坏。

sed命令行的语法格式为:
sed [-n] program [file-list]
sed [-n] -f program-file [file-list]
其中“program”表示命令行中的sed程序,“program-file”表示一个sed程序文件。“file-list”表示sed将要处理的普通数据文件。“-n”选项阻止sed将选定的行复制到标准输出上。

sed程序由符合如下语法的一行或多行命令构成:
[address][, address] instruction [argument-list]

其中“address”是可选的,如果省略则对输入的所有行进行处理。地址可以以行号、正则表达式或二者结合的方式表示。比如sed -n '3,/abcd/ p' filename输出第3行到匹配“abcd”的那行。其中“p”是打印指令。“$”表示最后一行。

指令包括:
d:删除指令(delete)。导致sed不输出被选择的行,并且不继续完成对该行的后续处理过程。
n:下一条指令(next)。输出当前选择的行(如果可以),然后从输入中读入下一行,并且从program或program-file中的下一条指令开始对新读入的行进行处理。
a:追加指令(append)。在当前选择的行之后插入一行或多行文本。如果在a指令前有两个地址,那么它将在选定的每一行之后添加文本。如果a指令前没有地址,它将在每行之后添加文本。
i:插入指令(insert)。与a指令同,只不过是将文本添加到选定的行之前。
c:修改指令(change)。与a和i指令类似,不同的是它将选定的行修改为新的文本。如果指定的是一个地址范围,c指令将整个范围内的行替换成新文本。
s:替换指令(subsitute)。与vim中的替换指令类似。语法为s/pattern/replacement/[g][p][w file]。g为global,替换所有匹配;p为print,打印替换过的行;w为写入文件。
p:打印指令(print)。将选定的行写入标准输出。
w file:写指令(write)。把选定的行写入文件。
r file:读指令(read)。从文件中读出内容并添加到选定的行之后。
q:退出指令(quit)。立即结束sed。

sed具有一此控制结构,可以控制程序的流程走向。常用的控制结构有:
!:取反操作,使得sed后面与其同一行的指令作用于没有该指令选择的每一行地址上。例如,“3!d”将删除除第3行外的所有行,而“$!p”将显示除最后一行外的所有行。
{}:将一组指令括起来,用于定义指令组。该组指令将作用于它前面的地址所选定的行,使用分号可将一行中的多条指令分隔开。
分支指令:sed不适合使用分支指令,如果需要,建议使用awk或Perl来编写程序。
:label:标识sed程序中的一个位置,适用于分支指令b或t
b [label]:无条件转移到label标识的命令。如果没有指出分支目标label,则跳过当前行中剩下的指令并从输入中读取下一行。
t [label]:如果从输入中读取的行使得s指令匹配成功,则转移到label标识的命令。如果没有指出分支目标label,则跳过当前行中剩下的指令并从输入中读取下一行。

sed有两个缓冲区:Pattern区和Hold区。Pattern区中保存着sed从输入中读取的行,所有的命令都工作在Pattern区上。Hold区作为临时缓冲区,可以用来暂存数据。Pattern区和Hold区之间进行数据传送的指令有:
g:将Hold区中的内容复制到Pattern区中。Pattern区中原来的内容将会丢失。
G:将一个换行符和Hold区中的内容追加到Pattern区中的内容之后。
h:将Pattern区中的内容复制到Hold区中。Hold区中原来的内容将会丢失。
H:将一个换行符和Pattern区的内容附加到Hold区中的内容之后。
x:交换Pattern区和Hold区中的内容。

相关文章推荐

LINUX下grep、sed、gawk汇总

  • 2015年01月29日 21:37
  • 515KB
  • 下载

Linux管理-sed

sed全名叫stream editor 流编辑器。
  • omg_cn
  • omg_cn
  • 2016年02月02日 22:58
  • 102

Linux命令shell脚本编程学习笔记-18章初识sed和gawk

第18章 初识sed和gawk18.1 文本处理sed编辑器 sed编辑器可以基于输入到命令行的或是存储在命令文本文件中的命令来处理数据流中的数据。 它每次读取一行,用提供的编辑器命令匹配数据、按...

《linux命令行与shell脚本编程大全》第三版 - 核心笔记(3/4):sed和gawk

《linux命令行与shell脚本编程大全》 全书4部分: ☆ 【1】linux命令行(1-10章) ☆ 【2】shell脚本编程基础(11-16章) ☆ 【3】高级shell脚本编程(17-...

第7章 sed、gawk介绍与正则表达式-----------(sed编辑器基础知识)

7.3sed编辑器基础知识          成功使用sed编辑器的关键是要了解其大量的命令和格式,这些命令和格式有助于自定义文本编辑。 7.3.1更多替换选项          替换标记要放在...

第7章 sed、gawk介绍与正则表达式-----------(gawk编辑器简单使用)

7.2gawk程序  sed编辑器是动态修改文本文件的便利工具,但是存在一定的局限性。gawk程序允许修改和重新组织文件中的数据。 gawk程序是Unix中原awk程序的GUN版本。awk程序在流...

Linux Shell脚本编程--sed命令详解

简介 sed 是一种在线编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的...

在线文本编辑器-没用过.rar

  • 2008年10月16日 12:25
  • 1.12MB
  • 下载

第7章 sed、gawk介绍与正则表达式-----------(正则表达式定义与类型)

7.4 正则表达式定义与类型          正则表达式是定义的、Linux实用程序用来筛选文本的模式模板。Linux实用程序在输入数据时,将正则表达式模式和数据进行匹配。如果数据与模式一致,它接...

第7章 sed、gawk介绍与正则表达式-----------(定义基本正则表达式(BRE)模式)

7.5定义BRE模式          最基本的BRE模式是匹配数据流中的文本字符。 7.5.1纯文本          sed编辑器和gawk程序中如何使用标准的文本字符串筛选数据。正则表达式...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Linux 编辑器(四)--gawk与sed
举报原因:
原因补充:

(最多只允许输入30个字)