|
<noscript></noscript>
<noscript><tr
valign="top"><td width="8"><img alt="" height="1" width="8"
src="//www.ibm.com/i/c.gif"/></td><td width="16"><img alt="" width="16"
height="16" src="//www.ibm.com/i/c.gif" mce_src="http://www.ibm.com/i/c.gif"/></td><td class="small"
width="122"><p><span class="ast">未显示需要 JavaScript
的文档选项</span></p></td></tr></noscript>
|
<!-- START RESERVED FOR FUTURE USE INCLUDE FILES--><!-- this content will be automatically generated across all content areas --><!-- END RESERVED FOR FUTURE USE INCLUDE FILES-->
|
级别: 初级
Daniel Robbins
(drobbins@gentoo.org
), President/CEO, Gentoo Technologies, Inc.
2001 年 10 月 01 日
sed 是十分强大和小巧的文本流编辑器。在本文章系列的第二篇中,Daniel Robbins 为您演示如何使用 sed 来执行字符串替换、创建更大的 sed 脚本以及如何使用 sed 的附加、插入和更改行命令。
<!-- START RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters -->
<!-- END RESERVED FOR FUTURE USE INCLUDE FILES-->
sed 是很有用(但常被遗忘)的 UNIX 流编辑器。在以批处理方式编辑文件或以有效方式创建 shell 脚本来修改现有文件方面,它是十分理想的工具。本文是
前一篇介绍 sed 文章
的续篇。
替换!
让我们看一下 sed 最有用的命令之一,替换命令。使用该命令,可以将特定字符串或匹配的规则表达式用另一个字符串替换。下面是该命令最基本用法的示例:
$ sed -e 's/foo/bar/' myfile.txt
|
上面的命令将 myfile.txt 中每行第一次出现的 'foo'(如果有的话)用字符串 'bar' 替换,然后将该文件内容输出到标准输出。请注意,我说的是
每行第一次出现
,尽管这通常不是您想要的。在进行字符串替换时,通常想执行全局替换。也就是说,要替换每行中的
所有
出现,如下所示:
$ sed -e 's/foo/bar/g' myfile.txt
|
在最后一个斜杠之后附加的 'g' 选项告诉 sed 执行全局替换。
关于 's///' 替换命令,还有其它几件要了解的事。首先,它是一个命令,并且只是一个命令,在所有上例中都没有指定地址。这意味着,'s///' 还可以与地址一起使用来控制要将命令应用到哪些行,如下所示:
$ sed -e '1,10s/enchantment/entrapment/g' myfile2.txt
|
上例将导致用短语 'entrapment' 替换所有出现的短语 'enchantment',但是只在第一到第十行(包括这两行)上这样做。
$ sed -e '/^$/,/^END/s/hills/mountains/g' myfile3.txt
|
该例将用 'mountains' 替换 'hills',但是,只从空行开始,到以三个字符 'END' 开始的行结束(包括这两行)的文本块上这样做。
关
于 's///' 命令的另一个妙处是 '/'
分隔符有许多替换选项。如果正在执行字符串替换,并且规则表达式或替换字符串中有许多斜杠,则可以通过在 's'
之后指定一个不同的字符来更改分隔符。例如,下例将把所有出现的 /usr/local 替换成 /usr:
$ sed -e 's:/usr/local:/usr:g' mylist.txt
|
在该例中,使用冒号作为分隔符。如果需要在规则表达式中指定分隔符字符,可以在它前面加入反斜杠。
规则表达式混乱
目前为止,我们只执行了简单的字符串替换。虽然这很方便,但是我们还可以匹配规则表达式。例如,以下 sed 命令将匹配从 '<' 开始、到 '>' 结束、并且在其中包含任意数量字符的短语。下例将删除该短语(用空字符串替换):
$ sed -e 's/<.*>//g' myfile.html
|
这是要从文件除去 HTML 标记的第一个很好的 sed 脚本尝试,但是由于规则表达式的特有规则,它不会很好地工作。原因何在?当 sed 试图在行中匹配规则表达式时,它要在行中查找
最长
的匹配。在我的
前一篇 sed 文章
中,这不成问题,因为我们使用的是 'd' 和 'p' 命令,这些命令总要删除或打印整行。但是,在使用 's///' 命令时,确实有很大不同,因为规则表达式匹配的整个部分将被目标字符串替换,或者,在本例中,被删除。这意味着,上例将把下行:
<b>This</b> is what <b>I</b> meant.
|
变成:
我们要的不是这个,而是:
幸
运的是,有一种简便方法来纠正该问题。我们不输入“'<' 字符后面跟有一些字符并以 '>'
字符结束”的规则表达式,而只需输入一个“'<' 字符后面跟有任意数量非 '>' 字符并以 '>'
字符结束”的规则表达式。这将与最短、而不是最长的可能性匹配。新命令如下:
$ sed -e 's/<[^>]*>//g' myfile.html
|
在上例中,'[^>]' 指定“非 '>'”字符,其后的 '*' 完成该表达式以表示“零或多个非 '>' 字符”。对几个 html 文件测试该命令,将它们管道输出到 "more",然后仔细查看其结果。
更多字符匹配
'[ ]' 规则表达式语法还有一些附加选项。要指定字符范围,只要字符不在第一个或最后一个位置,就可以使用 '-',如下所示:
这将匹配零或多个全部为 'a'、'b'、'c'...'v'、'w'、'x' 的字符。另外,可以使用 '[:space:]' 字符类来匹配空格。以下是可用字符类的相当完整的列表:
字符类
|
描述
|
[:alnum:] |
字母数字 [a-z A-Z 0-9] |
[:alpha:] |
字母 [a-z A-Z] |
[:blank:] |
空格或制表键 |
[:cntrl:] |
任何控制字符 |
[:digit:] |
数字 [0-9] |
[:graph:] |
任何可视字符(无空格) |
[:lower:] |
小写 [a-z] |
[:print:] |
非控制字符 |
[:punct:] |
标点字符 |
[:space:] |
空格 |
[:upper:] |
大写 [A-Z] |
[:xdigit:] |
十六进制数字 [0-9 a-f A-F] |
尽可能使用字符类是很有利的,因为它们可以更好地适应非英语 locale(包括某些必需的重音字符等等).
高级替换功能
我们已经看到如何执行简单甚至有些复杂的直接替换,但是 sed 还可以做更多的事。实际上可以引用匹配规则表达式的部分或全部,并使用这些部分来构造替换字符串。作为示例,假设您正在回复一条消息。下例将在每一行前面加上短语 "ralph said: ":
$ sed -e 's/.*/ralph said: &/' origmsg.txt
|
输出如下:
ralph said: Hiya Jim, ralph said: ralph said:
I sure like this sed stuff! ralph said:
|
该例的替换字符串中使用了 '&' 字符,该字符告诉 sed 插入整个匹配的规则表达式。因此,可以将与 '.*' 匹配的任何内容(行中的零或多个字符的最大组或整行)插入到替换字符串中的任何位置,甚至多次插入。这非常好,但 sed 甚至更强大。
那些极好的带反斜杠的圆括号
's///' 命令甚至比 '&' 更好,它允许我们在规则表达式中定义
区域
,然后可以在替换字符串中引用这些特定区域。作为示例,假设有一个包含以下文本的文件:
foo bar oni eeny meeny miny larry curly moe jimmy the weasel
|
现在假设要编写一个 sed 脚本,该脚本将把 "eeny meeny miny" 替换成 "Victor eeny-meeny Von miny" 等等。要这样做,首先要编写一个由空格分隔并与三个字符串匹配的规则表达式。
现在,将在其中每个感兴趣的区域两边插入带反斜杠的圆括号来定义区域:
除了要定义三个可在替换字符串中引用的逻辑区域以外,该规则表达式的工作原理将与第一个规则表达式相同。下面是最终脚本:
$ sed -e 's/\(.*\) \(.*\) \(.*\)/Victor \1-\2 Von \3/' myfile.txt
|
如您所见,通过输入 '\x'(其中,x 是从 1 开始的区域号)来引用每个由圆括号定界的区域。输入如下:
Victor foo-bar Von oni Victor eeny-meeny Von miny Victor larry-curly Von moe Victor jimmy-the Von weasel <!-- code sample is too wide -->
|
随着对 sed 越来越熟悉,您可以花最小力气来进行相当强大的文本处理。您可能想如何使用熟悉的脚本语言来处理这种问题 -- 能用一行代码轻易实现这样的解决方案吗?
组合使用
在
开始创建更复杂的 sed 脚本时,需要有输入多个命令的能力。有几种方法这样做。首先,可以在命令之间使用分号。例如,以下命令系列使用 '='
命令和 'p' 命令,'=' 命令告诉 sed 打印行号,'p' 命令明确告诉 sed 打印该行(因为处于 '-n' 模式)。
$ sed -n -e '=;p' myfile.txt
|
无
论什么时候指定了两个或更多命令,都按顺序将每个命令应用到文件的每一行。在上例中,首先将 '=' 命令应用到第 1 行,然后应用 'p'
命令。接着,sed 继续处理第 2 行,并重复该过程。虽然分号很方便,但是在某些场合下,它不能正常工作。另一种替换方法是使用两个 -e
选项来指定两个不同的命令:
$ sed -n -e '=' -e 'p' myfile.txt
|
然而,在使用更为复杂的附加和插入命令时,甚至多个 '-e' 选项也不能帮我们的忙。对于复杂的多行脚本,最好的方法是将命令放入一个单独的文件中。然后,用 -f 选项引用该脚本文件:
$ sed -n -f mycommands.sed myfile.txt
|
这种方法虽然可能不太方便,但总是管用。
一个地址的多个命令
有时,可能要指定应用到一个地址的多个命令。这在执行许多 's///' 以变换源文件中的字和语法时特别方便。要对一个地址执行多个命令,可在文件中输入 sed 命令,然后使用 '{ }' 字符将这些命令分组,如下所示:
1,20{ s/[Ll]inux/GNU\/Linux/g s/samba/Samba/g s/posix/POSIX/g }
|
上例将把三个替换命令应用到第 1 行到第 20 行(包括这两行)。还可以使用规则表达式地址或者二者的组合:
1,/^END/{ s/[Ll]inux/GNU\/Linux/g s/samba/Samba/g s/posix/POSIX/g p } <!-- code sample is too wide -->
|
该例将把 '{ }' 之间的所有命令应用到从第 1 行开始,到以字母 "END" 开始的行结束(如果在源文件中没发现 "END",则到文件结束)的所有行。
附加、插入和更改行
既然在单独的文件中编写 sed 脚本,我们可以利用附加、插入和更改行命令。这些命令将在当前行之后插入一行,在当前行之前插入一行,或者替换模式空间中的当前行。它们也可以用来将多行插入到输出。插入行命令用法如下:
i\ This line will be inserted before each line
|
如果不为该命令指定地址,那么它将应用到每一行,并产生如下的输出:
This line will be inserted before each line line 1 here
This line will be inserted before each line line 2 here
This line will be inserted before each line line 3 here
This line will be inserted before each line line 4 here
|
如果要在当前行之前插入多行,可以通过在前一行之后附加一个反斜杠来添加附加行,如下所示:
i\ insert this line\ and this one\ and this one\ and, uh, this one too.
|
附加命令的用法与之类似,但是它将把一行或多行插入到模式空间中的当前行之后。其用法如下:
a\ insert this line after each line. Thanks! :)
|
另一方面,“更改行”命令将实际
替换
模式空间中的当前行,其用法如下:
c\ You're history, original line! Muhahaha!
|
因为附加、插入和更改行命令需要在多行输入,所以将把它们输入到一个文本 sed 脚本中,然后通过使用 '-f' 选项告诉 sed 执行它们。使用其它方法将命令传递给 sed 会出现问题。
下一篇
在下一篇、也是本 sed 系列的最后一篇文章中,我将为您演示许多使用 sed 来完成不同类型任务的极佳实例。我将不仅为您显示脚本做些什么,还显示
为什么
那样做。完成之后,您将掌握更多有关如何在不同项目中使用 sed 的极佳知识。到时候见!
参考资料
关于作者
|
|
|
Daniel Robbins 居住在新墨西哥州的 Albuquerque。他是
Gentoo Technologies, Inc.
的总裁兼 CEO,Gentoo linux
(用于 PC 的高级 linux
)和 Portage 系统(Linux 的下一代端口系统)的创始人。他还是 Macmillan 书籍
Caldera OpenLinux Unleashed
、
SuSE linux
Unleashed
和
Samba Unleashed
的作者。Daniel 自小学二年级起就与计算机结下不解之缘,那时他首先接触的是 Logo 程序语言,并沉溺于 Pac-Man 游戏中。这也许就是他至今仍担任 SONY Electronic Publishing/
Psygnosis
的首席图形设计师的原因所在。Daniel 喜欢与妻子 Mary 和新出生的女儿 Hadassah 一起共度时光。可通过
drobbins@gentoo.org
与 Daniel 联系。
|
|
相关推荐
本资料全集将深入讲解这两个工具的使用,帮助你掌握它们的精髓,让你能够自如地完成各种字符串操作。 首先,让我们了解一下sed,全称为Stream Editor(流编辑器)。sed主要工作在输入流上,可以实时地对数据进行读...
### sed使用讲解 #### 一、sed简介与应用场景 sed(stream editor)是一种强大的文本处理工具,主要用于在命令行环境中对文件进行编辑操作。它能够高效地完成诸如查找、替换、删除、插入等任务,无需手动打开文件...
### sed 实例讲解 在Unix和类Unix系统中,sed(stream editor)是一个强大的文本处理工具,用于执行基本的文本转换工作。它读取输入流(可以是文件或标准输入),进行模式匹配和替换,然后将结果输出到标准输出。...
《Sed与Awk》是IT领域中关于文本处理的经典之作,主要讲解了两种强大的命令行工具:Sed(流编辑器)和Awk(数据处理语言)。这两款工具在Linux和Unix系统中广泛使用,尤其适用于数据提取、转换、报告生成等任务。 ...
《awk & sed 程序设计第二版》是IT领域中一本重要的系统管理资源,它深入浅出地讲解了awk和sed这两个强大的文本处理工具。这两款工具在Linux和Unix环境中广泛使用,对于系统管理员和程序员来说,掌握它们的基础和...
第六章深入讲解了sed中的保持空间(HoldSpace)与模式空间(PatternSpace)的命令,这些命令允许sed在处理文本时存储和操作更多的数据: - 交换保持空间和模式空间(SwapPatternSpacewithHoldSpace,xcommand)。 - ...
3. **正则表达式**:详细讲解如何在`awk`和`sed`中使用正则表达式进行模式匹配。 4. **脚本实例**:提供各种实际应用场景的脚本示例,如日志分析、CSV数据处理、文本格式转换等。 5. **高级特性**:涵盖`awk`的...
本文档主要讲解了正则表达式的基本用法和sed命令的应用,通过实际案例,详细介绍了正则表达式的匹配规则和sed命令的使用方法。 1. 正则表达式的基本用法 正则表达式是一种灵活的字符串匹配方式,广泛应用于 Unix/...
第四章:讲解如何编写sed脚本,包括sed的工作原理和脚本编写技巧。 第五章:涵盖了基本的sed命令,包括对文件进行插入、删除和修改操作的命令。 第六章:介绍了高级的sed命令,帮助读者更加深入地掌握sed的高级...
sed多行模式及循环部分,讲解了sed处理多行文本的能力,包括读取下一行数据附加到模式空间的命令(N),打印多行模式中的第一行(P),删除多行模式中的第一行(D)等。 在awk部分,手册介绍了awk命令语法、程序...
这本书详细地讲解了这两个工具的使用方法和高级技巧,旨在帮助读者提升对文本处理的掌控能力。 Sed是一种流编辑器,它可以从标准输入读取数据,进行处理,然后将结果输出到标准输出。Sed的强大之处在于它可以对文本...
本文将深入讲解`sed`命令的基本概念、功能以及在Shell脚本中的具体应用。 `sed`是一种非交互式的文本处理工具,它可以从标准输入读取数据,对数据进行处理,然后将结果输出到标准输出。`sed`的强大之处在于它可以...
总之,《Sed&Awk 2th Edition》是学习这两个经典工具的必备资料,无论你是初学者还是有经验的用户,都能从中受益匪浅。通过深入阅读和实践,你将能够灵活运用Sed和Awk解决各种文本处理挑战,成为文本处理领域的专家...
《Sed与Awk第二版》是一本深入探讨文本处理工具Sed和Awk的经典教程。这本书以高清的形式呈现,旨在帮助读者更好地理解和掌握这两种强大的命令行工具。Sed(Stream Editor)和Awk(Aho-Wedderburn-Kernighan)在Linux...
3. **awk入门**:讲解awk的语法基础,包括字段分割、内置变量和函数。 4. **awk模式与动作**:深入理解awk的模式匹配和执行动作,以及如何定义自己的函数。 5. **awk控制流程**:介绍if-else、while、for等控制结构...
压缩包内的`sed命令使用.docx`、`Sed命令学习笔记.pdf`、`sed使用手册.pdf`都是非常好的学习资料,它们将更深入地讲解sed命令的高级用法,包括模式匹配的细节、流编辑的技巧以及在实际工作中的应用案例。通过阅读...
接着是“sed与awk(第二版).pdf”,这本书是学习SED和AWK的经典之作。SED,全称Stream Editor,同样用于文本处理,但它通常用于对文本流进行行编辑,如替换、删除、插入等操作。这本书的第二版可能会深入讲解sed的...
在本书的第三版中,作者可能会详细讲解sed和awk的基本语法,包括正则表达式、模式空间、命令行选项等,并通过实例来展示如何使用这两个工具。同时,源代码文件(progs.tar.gz)很可能是书中各个例子的源代码集合,读者...