强大的Unix流编辑器sed在线极速入门 全三部分Word文档格式.docx

上传人:b****1 文档编号:4316423 上传时间:2023-05-03 格式:DOCX 页数:32 大小:63.80KB
下载 相关 举报
强大的Unix流编辑器sed在线极速入门 全三部分Word文档格式.docx_第1页
第1页 / 共32页
强大的Unix流编辑器sed在线极速入门 全三部分Word文档格式.docx_第2页
第2页 / 共32页
强大的Unix流编辑器sed在线极速入门 全三部分Word文档格式.docx_第3页
第3页 / 共32页
强大的Unix流编辑器sed在线极速入门 全三部分Word文档格式.docx_第4页
第4页 / 共32页
强大的Unix流编辑器sed在线极速入门 全三部分Word文档格式.docx_第5页
第5页 / 共32页
强大的Unix流编辑器sed在线极速入门 全三部分Word文档格式.docx_第6页
第6页 / 共32页
强大的Unix流编辑器sed在线极速入门 全三部分Word文档格式.docx_第7页
第7页 / 共32页
强大的Unix流编辑器sed在线极速入门 全三部分Word文档格式.docx_第8页
第8页 / 共32页
强大的Unix流编辑器sed在线极速入门 全三部分Word文档格式.docx_第9页
第9页 / 共32页
强大的Unix流编辑器sed在线极速入门 全三部分Word文档格式.docx_第10页
第10页 / 共32页
强大的Unix流编辑器sed在线极速入门 全三部分Word文档格式.docx_第11页
第11页 / 共32页
强大的Unix流编辑器sed在线极速入门 全三部分Word文档格式.docx_第12页
第12页 / 共32页
强大的Unix流编辑器sed在线极速入门 全三部分Word文档格式.docx_第13页
第13页 / 共32页
强大的Unix流编辑器sed在线极速入门 全三部分Word文档格式.docx_第14页
第14页 / 共32页
强大的Unix流编辑器sed在线极速入门 全三部分Word文档格式.docx_第15页
第15页 / 共32页
强大的Unix流编辑器sed在线极速入门 全三部分Word文档格式.docx_第16页
第16页 / 共32页
强大的Unix流编辑器sed在线极速入门 全三部分Word文档格式.docx_第17页
第17页 / 共32页
强大的Unix流编辑器sed在线极速入门 全三部分Word文档格式.docx_第18页
第18页 / 共32页
强大的Unix流编辑器sed在线极速入门 全三部分Word文档格式.docx_第19页
第19页 / 共32页
强大的Unix流编辑器sed在线极速入门 全三部分Word文档格式.docx_第20页
第20页 / 共32页
亲,该文档总共32页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

强大的Unix流编辑器sed在线极速入门 全三部分Word文档格式.docx

《强大的Unix流编辑器sed在线极速入门 全三部分Word文档格式.docx》由会员分享,可在线阅读,更多相关《强大的Unix流编辑器sed在线极速入门 全三部分Word文档格式.docx(32页珍藏版)》请在冰点文库上搜索。

强大的Unix流编辑器sed在线极速入门 全三部分Word文档格式.docx

beta"

期间格外长(2年!

)。

例如,sed3.02a已有两年,甚至3.02.80也有一年,但它们仍不能(在2000年8月写本文章时)在ftp.gnu.org上获得。

正确的sed

在本系列中,将使用GNUsed3.02.80。

在即将出现的本系列后续部分中,某些(但非常少)最高级的示例将不能在GNUsed3.02或3.02a中使用。

如果您使用的不是GNUsed,那么结果可能会不同。

现在为什么不花些时间安装GNUsed3.02.80呢?

那样,不仅可以为本系列的余下部分作好准备,而且还可以使用可能是目前最好的sed。

sed示例

sed通过对输入数据执行任意数量用户指定的编辑操作(“命令”)来工作。

sed是基于行的,因此按顺序对每一行执行命令。

然后,sed将其结果写入标准输出(stdout),它不修改任何输入文件。

让我们看一些示例。

头几个会有些奇怪,因为我要用它们演示sed如何工作,而不是执行任何有用的任务。

然而,如果您是sed新手,那么理解它们是十分重要的。

下面是第一个示例:

1.$sed-e'

d'

/etc/services

复制代码

如果输入该命令,将得不到任何输出。

那么,发生了什么?

在该例中,用一个编辑命令'

调用sed。

sed打开/etc/services文件,将一行读入其模式缓冲区,执行编辑命令(“删除行”),然后打印模式缓冲区(缓冲区已为空)。

然后,它对后面的每一行重复这些步骤。

这不会产生输出,因为"

d"

命令除去了模式缓冲区中的每一行!

在该例中,还有几件事要注意。

首先,根本没有修改/etc/services。

这还是因为sed只读取在命令行指定的文件,将其用作输入--它不试图修改该文件。

第二件要注意的事是sed是面向行的。

'

命令不是简单地告诉sed一下子删除所有输入数据。

相反,sed逐行将/etc/services的每一行读入其称为模式缓冲区的内部缓冲区。

一旦将一行读入模式缓冲区,它就执行'

命令,然后打印模式缓冲区的内容(在本例中没有内容)。

我将在后面为您演示如何使用地址范围来控制将命令应用到哪些行--但是,如果不使用地址,命令将应用到所有行。

第三件要注意的事是括起'

命令的单引号的用法。

养成使用单引号来括起sed命令的习惯是个好注意,这样可以禁用shell扩展。

另一个sed示例

下面是使用sed从输出流除去/etc/services文件第一行的示例:

1d'

/etc/services|more

如您所见,除了前面有'

1'

之外,该命令与第一个'

命令十分类似。

如果您猜到'

指的是第一行,那您就猜对了。

与第一个示例中只使用'

不同的是,这一次使用的'

前面有一个可选的数字地址。

通过使用地址,可以告诉sed只对某一或某些特定行进行编辑。

地址范围

现在,让我们看一下如何指定地址范围。

在本例中,sed将删除输出的第1到10行:

1,10d'

当用逗号将两个地址分开时,sed将把后面的命令应用到从第一个地址开始、到第二个地址结束的范围。

在本例中,将'

命令应用到第1到10行(包括这两行)。

所有其它行都被忽略。

带规则表达式的地址

现在演示一个更有用的示例。

假设要查看/etc/services文件的内容,但是对查看其中包括的注释部分不感兴趣。

如您所知,可以通过以'

#'

字符开头的行在/etc/services文件中放置注释。

为了避免注释,我们希望sed删除以'

开始的行。

以下是具体做法:

/^#/d'

试一下该例,看看发生了什么。

您将注意到,sed成功完成了预期任务。

现在,让我们分析发生的情况。

要理解'

命令,首先需要对其剖析。

首先,让我们除去'

--这是我们前面所使用的同一个删除行命令。

新增加的是'

/^#/'

部分,它是一种新的规则表达式地址。

规则表达式地址总是由斜杠括起。

它们指定一种模式,紧跟在规则表达式地址之后的命令将仅适用于正好与该特定模式匹配的行。

因此,'

是一个规则表达式。

但是,它做些什么呢?

很明显,现在该复习规则表达式了。

规则表达式复习

可以使用规则表达式来表示可能会在文本中发现的模式。

您在shell命令行中用过'

*'

字符吗?

这种用法与规则表达式类似,但并不相同。

下面是可以在规则表达式中使用的特殊字符:

字符 

 

描述

与行首匹配

与行末尾匹配

\w 

与任一个字符匹配

将与前一个字符的零或多个出现匹配

[] 

与[]之内的所有字符匹配

感受规则表达式的最好方法可能是看几个示例。

所有这些示例都将被sed作为合法地址接受,这些地址出现在命令的左边。

下面是几个示例:

规则表达式 

/./ 

将与包含至少一个字符的任何行匹配

/../ 

将与包含至少两个字符的任何行匹配

/^#/ 

将与以'

开始的任何行匹配

/^$/ 

将与所有空行匹配

/}^/ 

}'

(无空格)结束的任何行匹配

/}*^/ 

后面跟有零或多个空格结束的任何行匹配

/[abc]/ 

将与包含小写'

a'

、'

b'

或'

c'

的任何行匹配

/^[abc]/ 

在这些示例中,鼓励您尝试几个。

花一些时间熟悉规则表达式,然后尝试几个自己创建的规则表达式。

可以如下使用regexp:

/regexp/d'

/path/to/my/test/file|more

这将导致sed删除任何匹配的行。

然而,通过告诉sed打印regexp匹配并删除不匹配的内容,而不是与之相反的方法,会更有利于熟悉规则表达式。

可以用以下命令这样做:

1.$sed-n-e'

/regexp/p'

请注意新的'

-n'

选项,该选项告诉sed除非明确要求打印模式空间,否则不这样做。

您还会注意到,我们用'

p'

命令替换了'

命令,如您所猜想的那样,这明确要求sed打印模式空间。

就这样,将只打印匹配部分。

有关地址的更多内容

目前为止,我们已经看到了行地址、行范围地址和regexp地址。

但是,还有更多的可能。

我们可以指定两个用逗号分开的规则表达式,sed将与所有从匹配第一个规则表达式的第一行开始,到匹配第二个规则表达式的行结束(包括该行)的所有行匹配。

例如,以下命令将打印从包含"

BEGIN"

的行开始,并且以包含"

END"

的行结束的文本块:

/BEGIN/,/END/p'

/my/test/file|more

如果没发现"

,那么将不打印数据。

如果发现了"

,但是在这之后的所有行中都没发现"

,那么将打印所有后续行。

发生这种情况是因为sed面向流的特性--它不知道是否会出现"

C源代码示例

如果只要打印C源文件中的main()函数,可输入:

/main[[:

space:

]]*(/,/^}/p'

sourcefile.c|more

该命令有两个规则表达式'

]]*(/'

和'

/^}/'

,以及一个命令'

第一个规则表达式将与后面依次跟有任意数量的空格或制表键以及开始圆括号的字符串"

main"

匹配。

这应该与一般ANSICmain()声明的开始匹配。

在这个特别的规则表达式中,出现了'

[[:

]]'

字符类。

这只是一个特殊的关键字,它告诉sed与TAB或空格匹配。

如果愿意的话,可以不输入'

,而输入'

['

,然后是空格字母,然后是-V,然后再输入制表键字母和'

]'

--Control-V告诉bash要插入“真正”的制表键,而不是执行命令扩展。

使用'

命令类(特别是在脚本中)会更清楚。

好,现在看一下第二个regexp。

/^}'

将与任何出现在新行行首的'

字符匹配。

如果代码的格式很好,那么这将与main()函数的结束花括号匹配。

如果格式不好,则不会正确匹配--这是执行模式匹配任务的一件棘手之事。

因为是处于'

安静方式,所以'

命令还是完成其惯有任务,即明确告诉sed打印该行。

试着对C源文件运行该命令--它应该输出整个main(){}块,包括开始的"

main()"

和结束的'

分享到:

微信新浪微博腾讯微博QQ空间人人网豆瓣网

分享到:

QQ好友和群

QQ空间

腾讯微博

腾讯朋友

微信

收藏6

分享

淘帖

支持

反对

回复

使用道具举报

2楼

楼主|发表于2008-10-1410:

49|只看该作者

类Unix流编辑器sed在线极速入门第二部分

sed是十分强大和小巧的文本流编辑器。

在本文章系列的第二部分中,将为您演示如何使用sed来执行字符串替换、创建更大的sed脚本以及如何使用sed的附加、插入和更改行命令。

sed是很有用(但常被遗忘)的UNIX流编辑器。

在以批处理方式编辑文件或以有效方式创建shell脚本来修改现有文件方面,它是十分理想的工具。

本文是前一部分介绍sed文章的续篇。

替换!

让我们看一下sed最有用的命令之一,替换命令。

使用该命令,可以将特定字符串或匹配的规则表达式用另一个字符串替换。

下面是该命令最基本用法的示例:

s/foo/bar/'

myfile.txt

上面的命令将myfile.txt中每行第一次出现的'

foo'

(如果有的话)用字符串'

bar'

替换,然后将该文件内容输出到标准输出。

请注意,我说的是每行第一次出现,尽管这通常不是您想要的。

在进行字符串替换时,通常想执行全局替换。

也就是说,要替换每行中的所有出现,如下所示:

s/foo/bar/g'

myfile.txt

在最后一个斜杠之后附加的'

g'

选项告诉sed执行全局替换。

关于'

s///'

替换命令,还有其它几件要了解的事。

首先,它是一个命令,并且只是一个命令,在所有上例中都没有指定地址。

这意味着,'

还可以与地址一起使用来控制要将命令应用到哪些行,如下所示:

1,10s/enchantment/entrapment/g'

myfile2.txt

上例将导致用短语'

entrapment'

替换所有出现的短语'

enchantment'

,但是只在第一到第十行(包括这两行)上这样做。

/^$/,/^END/s/hills/mountains/g'

myfile3.txt

该例将用'

mountains'

替换'

hills'

,但是,只从空行开始,到以三个字符'

END'

开始的行结束(包括这两行)的文本块上这样做。

命令的另一个妙处是'

/'

分隔符有许多替换选项。

如果正在执行字符串替换,并且规则表达式或替换字符串中有许多斜杠,则可以通过在'

s'

之后指定一个不同的字符来更改分隔符。

例如,下例将把所有出现的/usr/local替换成/usr:

s:

/usr/local:

/usr:

mylist.txt

在该例中,使用冒号作为分隔符。

如果需要在规则表达式中指定分隔符字符,可以在它前面加入反斜杠。

规则表达式混乱

目前为止,我们只执行了简单的字符串替换。

虽然这很方便,但是我们还可以匹配规则表达式。

例如,以下sed命令将匹配从'

<

开始、到'

>

结束、并且在其中包含任意数量字符的短语。

下例将删除该短语(用空字符串替换):

s/<

.*>

//g'

myfile.html

这是要从文件除去HTML标记的第一个很好的sed脚本尝试,但是由于规则表达式的特有规则,它不会很好地工作。

原因何在?

当sed试图在行中匹配规则表达式时,它要在行中查找最长的匹配。

在前一部分中,这不成问题,因为我们使用的是'

命令,这些命令总要删除或打印整行。

但是,在使用'

命令时,确实有很大不同,因为规则表达式匹配的整个部分将被目标字符串替换,或者,在本例中,被删除。

这意味着,上例将把下行:

1.<

b>

This<

/b>

iswhat<

I<

meant.

变成:

meant.

我们要的不是这个,而是:

ThisiswhatImeant.

幸运的是,有一种简便方法来纠正该问题。

我们不输入“'

字符后面跟有一些字符并以'

字符结束”的规则表达式,而只需输入一个“'

字符后面跟有任意数量非'

字符并以'

字符结束”的规则表达式。

这将与最短、而不是最长的可能性匹配。

新命令如下:

[^>

]*>

在上例中,'

指定“非'

”字符,其后的'

完成该表达式以表示“零或多个非'

字符”。

对几个html文件测试该命令,将它们管道输出到"

more"

,然后仔细查看其结果。

更多字符匹配

[]'

规则表达式语法还有一些附加选项。

要指定字符范围,只要字符不在第一个或最后一个位置,就可以使用'

-'

,如下所示:

[a-x]*'

这将匹配零或多个全部为'

...'

v'

w'

x'

的字符。

另外,可以使用'

[:

字符类来匹配空格。

以下是可用字符类的相当完整的列表:

字符类 

alnum:

字母数字[a-zA-Z0-9]

alpha:

字母[a-zA-Z]

blank:

空格或制表键

cntrl:

任何控制字符

digit:

数字[0-9]

graph:

任何可视字符(无空格)

lower:

小写[a-z]

print:

非控制字符

punct:

标点字符

空格

upper:

大写[A-Z]

xdigit:

十六进制数字[0-9a-fA-F]

尽可能使用字符类是很有利的,因为它们可以更好地适应非英语locale(包括某些必需的重音字符等等).

高级替换功能

我们已经看到如何执行简单甚至有些复杂的直接替换,但是sed还可以做更多的事。

实际上可以引用匹配规则表达式的部分或全部,并使用这些部分来构造替换字符串。

作为示例,假设您正在回复一条消息。

下例将在每一行前面加上短语"

ralphsaid:

"

s/.*/ralphsaid:

&

origmsg.txt

输出如下:

HiyaJim,ralphsaid:

ralphsaid:

Isurelikethissedstuff!

该例的替换字符串中使用了'

&

字符,该字符告诉sed插入整个匹配的规则表达式。

因此,可以将与'

.*'

匹配的任何内容(行中的零或多个字符的最大组或整行)插入到替换字符串中的任何位置,甚至多次插入。

这非常好,但sed甚至更强大。

那些极好的带反斜杠的圆括号

命令甚至比'

更好,它允许我们在规则表达式中定义区域,然后可以在替换字符串中引用这些特定区域。

作为示例,假设有一个包含以下文本的文件:

foobaronieenymeenyminylarrycurlymoejimmytheweasel

现在假设要编写一个sed脚本,该脚本将把"

eenymeenyminy"

替换成"

Victoreeny-meenyVonminy"

等等。

要这样做,首先要编写一个由空格分隔并与三个字符串匹配的规则表达式。

1.'

.*.*.*'

现在,将在其中每个感兴趣的区域两边插入带反斜杠的圆括号来定义区域:

\(.*\)\(.*\)\(.*\)'

除了要定义三个可在替换字符串中引用的逻辑区域以外,该规则表达式的工作原理将与第一个规则表达式相同。

下面是最终脚本:

s/\(.*\)\(.*\)\(.*\)/Victor\1-\2Von\3/'

如您所见,通过输入'

\x'

(其中,x是从1开始的区域号)来引用每个由圆括号定界的区域。

输入如下:

Victorfoo-barVononiVictoreeny-meenyVonminyVictorlarry-curlyVonmoeVictorjimmy-theVonweasel

随着对sed越来越熟悉,您可以花最小力气来进行相当强大的文本处理。

您可能想如何使用熟悉的脚本语言来处理这种问题--能用一行代码轻易实现这样的解决方案吗?

组合使用

在开始创建更复杂的sed脚本时,需要有输入多个命令的能力。

有几种方法这样做。

首先,可以在命令之间使用分号。

例如,以下命令系列使用'

='

命令和'

命令,'

命令告诉sed打印行号,'

命令明确告诉sed打印该行(因为处于'

模式)。

=;

无论什么时候指定了两个或更多命令,都按顺序将每个命令应用到文件的每一行。

在上例中,首先将'

命令应用到第1行,然后应用'

命令。

接着,sed继续处理第2行,并重复该过程。

虽然分号很方便,但是在某些场合下,它不能正常工作。

另一种替换方法是使用两个-e选项来指定两个不同的命令:

-e'

然而,在使用更为复杂的附加和插入命令时,甚至多个'

-e'

选项也不能帮我们的忙。

对于复杂的多行脚本,最好的方法是将命令放入一个单独的文件中。

然后,用-f选项引用该脚本文件:

1.$sed-n-fmycommands.sedmyfile.txt

这种方法虽然可能不太方便,但总是管用。

一个地址的多个命令

有时,可能要指定应用到一个地址的多个命令。

这在执行许多'

以变换源文件中的字和语法时特别方便。

要对一个地址执行多个命令,可在文件中输入sed命令,然后使

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 人文社科 > 教育学心理学

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2