\>锚定单词的结束,如/love\>/匹配包含以love结尾的单词的行。
x\{m\}重复字符x,m次,如:
/0\{5\}/匹配包含5个o的行。
x\{m,\}重复字符x,至少m次,如:
/o\{5,\}/匹配至少有5个o的行。
x\{m,n\}重复字符x,至少m次,不多于n次,如:
/o\{5,10\}/匹配5--10个o的行。
5.实例
5.1删除:
d命令
* $sed'2d'example-----删除example文件的第二行。
* $sed'2,$d'example-----删除example文件的第二行到末尾所有行。
* $sed'$d'example-----删除example文件的最后一行。
* $sed'/test/'dexample-----删除example文件所有包含test的行。
5.2替换:
s命令
* $sed's/test/mytest/g'example-----在整行范围内把test替换为mytest。
如果没有g标记,则只有每行第一个匹配的test被替换成mytest。
* $sed-n's/^test/mytest/p'example-----(-n)选项和p标志一起使用表示只打印那些发生替换的行。
也就是说,如果某一行开头的test被替换成mytest,就打印它。
* $sed's/^192.168.0.1/&localhost/'example-----&符号表示替换换字符串中被找到的部份。
所有以192.168.0.1开头的行都会被替换成它自已加localhost,变成192.168.0.1localhost。
* $sed-n's/\(love\)able/\1rs/p'example-----love被标记为1,所有loveable会被替换成lovers,而且替换的行会被打印出来。
* $sed's#10#100#g'example-----不论什么字符,紧跟着s命令的都被认为是新的分隔符,所以,“#”在这里是分隔符,代替了默认的“/”分隔符。
表示把所有10替换成100。
5.3选定行的范围:
逗号
* $sed-n'/test/,/check/p'example-----所有在模板test和check所确定的范围内的行都被打印。
* $sed-n'5,/^test/p'example-----打印从第五行开始到第一个包含以test开始的行之间的所有行。
* $sed'/test/,/check/s/$/sedtest/'example-----对于模板test和west之间的行,每行的末尾用字符串sedtest替换。
5.4多点编辑:
e命令
* $sed-e'1,5d'-e's/test/check/'example-----(-e)选项允许在同一行里执行多条命令。
如例子所示,第一条命令删除1至5行,第二条命令用check替换test。
命令的执行顺序对结果有影响。
如果两个命令都是替换命令,那么第一个替换命令将影响第二个替换命令的结果。
* $sed--expression='s/test/check/'--expression='/love/d'example-----一个比-e更好的命令是--expression。
它能给sed表达式赋值。
5.5从文件读入:
r命令
* $sed'/test/rfile'example-----file里的内容被读进来,显示在与test匹配的行后面,如果匹配多行,则file的内容将显示在所有匹配行的下面。
5.6写入文件:
w命令
* $sed-n'/test/wfile'example-----在example中所有包含test的行都被写入file里。
5.7追加命令:
a命令
* $sed'/^test/a\\--->thisisaexample'example<-----'thisisaexample'被追加到以test开头的行后面,sed要求命令a后面有一个反斜杠。
5.8插入:
i命令
$sed'/test/i\\
newline
-------------------------'example
如果test被匹配,则把反斜杠后面的文本插入到匹配行的前面。
下一个:
n命令
* $sed'/test/{n;s/aa/bb/;}'example-----如果test被匹配,则移动到匹配行的下一行,替换这一行的aa,变为bb,并打印该行,然后继续。
5.9变形:
y命令
* $sed'1,10y/abcde/ABCDE/'example-----把1--10行内所有abcde转变为大写,注意,正则表达式元字符不能使用这个命令。
5.10退出:
q命令
* $sed'10q'example-----打印完第10行后,退出sed。
5.11保持和获取:
h命令和G命令
* $sed-e'/test/h'-e'$Gexample-----在sed处理文件的时候,每一行都被保存在一个叫模式空间的临时缓冲区中,除非行被删除或者输出被取消,否则所有被处理的行都将打印在屏幕上。
接着模式空间被清空,并存入新的一行等待处理。
在这个例子里,匹配test的行被找到后,将存入模式空间,h命令将其复制并存入一个称为保持缓存区的特殊缓冲区内。
第二条语句的意思是,当到达最后一行后,G命令取出保持缓冲区的行,然后把它放回模式空间中,且追加到现在已经存在于模式空间中的行的末尾。
在这个例子中就是追加到最后一行。
简单来说,任何包含test的行都被复制并追加到该文件的末尾。
5.12保持和互换:
h命令和x命令
* $sed-e'/test/h'-e'/check/x'example-----互换模式空间和保持缓冲区的内容。
也就是把包含test与check的行互换。
6.脚本
Sed脚本是一个sed的命令清单,启动Sed时以-f选项引导脚本文件名。
Sed对于脚本中输入的命令非常挑剔,在命令的末尾不能有任何空白或文本,如果在一行中有多个命令,要用分号分隔。
以#开头的行为注释行,且不能跨行。
7.小技巧
* 在sed的命令行中引用shell变量时要使用双引号,而不是通常所用的单引号。
下面是一个根据name变量的内容来删除named.conf文件中zone段的脚本:
name='zone\"localhost"'
sed"/$name/,/};/d"named.conf
awk
awk是一种程序语言,对文档资料的处理具有很强的功能。
awk名称是由它三个最初设计者的姓氏的第一个字母而命名的:
AlfredV.Aho、PeterJ.Weinberger、BrianW.Kernighan。
awk最初在1977年完成。
1985年发表了一个新版本的awk,它的功能比旧版本增强了不少。
awk能够用很短的程序对文档里的资料做修改、比较、提取、打印等处理。
如果使用C或Pascal等语言编写程序完成上述的任务会十分不方便而且很花费时间,所写的程序也会很大。
awk不仅仅是一个编程语言,它还是linux系统管理员和程序员的一个不可缺少的工具。
awk语言本身十分好学,易于掌握,并且特别的灵活。
gawk是GNU计划下所做的awk,gawk最初在1986年完成,之后不断地被改进、更新。
gawk包含awk的所有功能。
1.gawk的主要功能
gawk的主要功能是针对文件的每一行(line),也就是每一条记录,搜寻指定的格式。
当某一行符合指定的格式时,gawk就会在此行执行被指定的动作。
gawk依此方式自动处理输入文件的每一行直到输入文件档案结束。
gawk经常用在如下的几个方面:
·根据要求选择文件的某几行,几列或部分字段以供显示输出。
·分析文档中的某一个字出现的频率、位置等。
·根据某一个文档的信息准备格式化输出。
·以一个功能十分强大的方式过滤输出文档。
·根据文档中的数值进行计算。
2.如何执行gawk程序
基本上有两种方法可以执行gawk程序。
如果gawk程序很短,则可以将gawk直接写在命令行,如下所示:
gawk'program'input-file1input-file2...
其中program包括一些pattern和action。
如果gawk程序较长,较为方便的做法是将gawk程序存在一个文件中,
gawk的格式如下所示:
gawk-fprogram-fileinput-file1input-file2...
gawk程序的文件不止一个时,执行gawk的格式如下所示:
gawk-fprogram-file1-fprogram-file2...input-file1input-file2...
3.文件、记录和字段
一般情况下,gawk可以处理文件中的数值数据,但也可以处理字符串信息。
如果数据没有存储在文件中,可以通过管道命令和其他的重定向方法给gawk提供输入。
当然,gawk只能处理文本文件(ASCII码文件)。
电话号码本就是一个gawk可以处理的文件的简单例子。
电话号码本由很多条目组成,每一个条目都有同样的格式:
姓、名、地址、电话号码。
每一个条目都是按字母顺序排列。
在gawk中,每一个这样的条目叫做一个记录。
它是一个完整的数据的集合。
例如,电话号码本中的SmithJohn这个条目,包括他的地址和电话号码,就是一条记录。
记录中的每一项叫做一个字段。
在gawk中,字段是最基本的单位。
多个记录的集合组成了一个文件。
大多数情况下,字段之间由一个特殊的字符分开,像空格、TAB、分号等。
这些字符叫做字段分隔符。
请看下面这个/etc/passwd文件:
tparker;t36s62hs;501;101;TimParker;/home/tparker;/bin/bash
etreijs;2ys639dj3;502;101;EdTreijs;/home/etreijs;/bin/tcsh
ychow;1h27sj;503;101;YvonneChow;/home/ychow;/bin/bash
你可以看出/etc/passwd文件使用分号作为字段分隔符。
/etc/passwd文件中的每一行都包括七个字段:
用户名;口令;用户ID;工作组ID;注释;home目录;启始的外壳。
如果你想要查找第六个字段,只需数过五个分号即可。
但考虑到以下电话号码本的例子,你就会发现一些问题:
SmithJohn13WilsonSt.555-1283
SmithJohn2736ArtsideDrApt123555-2736
SmithJohn125WestmountCr555-1726
虽然我们能够分辨出每个记录包括四个字段,但gawk却无能为力。
电话号码本使用空格作为分隔符,所以gawk认为Smith是第一个字段,John是第二个字段,13是第三个字段,依次类推。
就gawk而言,如果用空格作为字段分隔符的话,则第一个记录有六个字段,而第二个记录有八个字段。
所以,我们必须找出一个更好的字段分隔符。
例如,像下面一样使用斜杠作为字段分隔符:
Smith/John/13WilsonSt./555-1283
Smith/John/2736ArtsideDr/Apt/123/555-2736
Smith/John/125WestmountCr/555-1726
如果你没有指定其他的字符作为字段分隔符,那么gawk将缺省地使用空格或TAB作为字段分隔符。
4.模式和动作
在gawk语言中每一个命令都由两部分组成:
一个模式(pattern)和一个相应的动作
(action)。
只要模式符合,gawk就会执行相应的动作。
其中模式部分用两个斜杠括起来,而动
作部分用一对花括号括起来。
例如:
/pattern1/{action1}
/pattern2/{action2}
/pattern3/{action3}
所有的gawk程序都是由这样的一对对的模式和动作组成的。
其中模式或动作都能够被省
略,但是两个不能同时被省略。
如果模式被省略,则对于作为输入的文件里面的每一行,动作
都会被执行。
如果动作被省略,则缺省的动作被执行,既显示出所有符合模式的输入行而不做
任何的改动。
下面是一个简单的例子,因为gawk程序很短,所以将gawk程序直接写在外壳命令行:
gawk'/tparker/'/etc/passwd
此程序在上面提到的/etc/passwd文件中寻找符合tparker模式的记录并显示(此例中没有动作,所以缺省的动作被执行)。
让我们再看一个例子:
gawk'/UNIX/{print$2}'file2.data
此命令将逐行查找file2.data文件中包含UNIX的记录,并打印这些记录的第二个字段。
你也可以在一个命令中使用多个模式和动作对,例如:
gawk'/scandal/{print$1}/rumor/{print$2}'gossip_file
此命令搜索文件gossip_file中包括scandal的记录,并打印第一个字段。
然后再从头搜索
gossip_file中包括rumor的记录,并打印第二个字段。
5.比较运算和数值运算
gawk有很多比较运算符,下面列出重要的几个:
==相等
!
=不相等
>大于
<小于
>=大于等于
<=小于等于
例如:
gawk'$4>100'testfile
将会显示文件testfile中那些第四个字段大于100的记录。
下表列出了gawk中基本的数值运算符。
运算符说明示例
+加法运算2+6
-减法运算6-3
*乘法运算2*5
/除法运算8/4
^乘方运算3^2(=9)
%求余数9%4(=1)
例如:
{print$3/2}
显示第三个字段被2除的结果。
在gawk中,运算符的优先权和一般的数学运算的优先权一样。
例如:
{print$1+$2*$3}
显示第二个字段和第三个字段相乘,然后和第一个字段相加的结果。
你也可以用括号改变优先次序。
例如:
{print($1+$2)*$3}
显示第一个字段和第二个字段相加,然后和第三个字段相乘的结果。
6.内部函数
gawk中有各种的内部函数,现在介绍如下:
6.1随机数和数学函数
sqrt(x)求x的平方根
sin(x)求x的正弦函数
cos(x)求x的余弦函数
atan2(x,y)求x/y的余切函数
log(x)求x的自然对数
exp(x)求x的e次方
int(x)求x的整数部分
rand()求0和1之间的随机数
srand(x)将x设置为rand()的种子数
6.2字符串的内部函数
·index(in,find)在字符串in中寻找字符串find第一次出现的地方,返回值是字符串
find出现在字符串in里面的位置。
如果在字符串in里面找不到字符串find,则返回值为0。
例如:
printindex("peanut","an")
显示结果3。
·length(string)求出string有几个字符。
例如:
length("abcde")
显示结果5。
·match(string,regexp)在字符串string中寻找符合regexp的最长、最靠左边的子字符串。
返回值是regexp在string的开始位置,即index值。
match函数将会设置系统变量
RSTART等于index的值,系统变量RLENGTH等于符合的字符个数。
如果不符合,则会
设置RSTART为0、RLENGTH为-1。
·sprintf(format,expression1,...)和printf类似,但是sprintf并不显示,而是返回字符串。
例如:
sprintf("pi=%.2f(approx.)",22/7)
返回的字符串为pi=3.14(approx.)
·sub(regexp,replacement,target)在字符串target中寻找符合regexp的最长、最靠左的
地方,以字串replacement代替最左边的regexp。
例如:
str="water,water,everywhere"
sub(/at/,"ith",str)
结果字符串str会变成wither,water,everywhere
·gsub(regexp,replacement,target)与前面的sub类似。
在字符串target中寻找符合regexp的所有地方,以字符串replacement代替所有的regexp。
例如:
str="water,water,everywhere"
gsub(/at/,"ith",str)
结果字符串str会变成wither,wither,everywhere
·substr(string,start,length)返回字符串string的子字符串,这个子字符串的长度为length,从第start个位置开始。
例如:
substr("washington",5,3)
返回值为ing
如果没有length,则返回的子字符串是从第start个位置开始至结束。
例如:
substr("washington",5)
返回值为ington。
·tolower(string)将字符串string的大写字母改为小写字母。
例如:
tolower(