`
saybody
  • 浏览: 903528 次
  • 性别: Icon_minigender_2
  • 来自: 西安
文章分类
社区版块
存档分类
最新评论

sed 经典讲解

阅读更多

参考链接:http://www.ibm.com/developerworks/cn/linux/shell/sed/sed-2/

作为一个练习:如何将C++源代码中的//型注释转换为/* */型注释?

答案在这:
sed 's/\/\/\(.*\)/\/* \1 *\//' *.cpp

developerWorks 中国 > Linux >

通用线程 -- sed 实例,第 2 部分

developerWorks
文档选项
<noscript></noscript> <noscript>&lt;tr valign="top"&gt;&lt;td width="8"&gt;&lt;img alt="" height="1" width="8" src="//www.ibm.com/i/c.gif"/&gt;&lt;/td&gt;&lt;td width="16"&gt;&lt;img alt="" width="16" height="16" src="//www.ibm.com/i/c.gif" mce_src="http://www.ibm.com/i/c.gif"/&gt;&lt;/td&gt;&lt;td class="small" width="122"&gt;&lt;p&gt;&lt;span class="ast"&gt;未显示需要 JavaScript 的文档选项&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;</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.  

变成:

 meant.  

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

 This is what I meant.  

幸 运的是,有一种简便方法来纠正该问题。我们不输入“'<' 字符后面跟有一些字符并以 '>' 字符结束”的规则表达式,而只需输入一个“'<' 字符后面跟有任意数量非 '>' 字符并以 '>' 字符结束”的规则表达式。这将与最短、而不是最长的可能性匹配。新命令如下:

 $ sed -e 's/<[^>]*>//g' myfile.html 

在上例中,'[^>]' 指定“非 '>'”字符,其后的 '*' 完成该表达式以表示“零或多个非 '>' 字符”。对几个 html 文件测试该命令,将它们管道输出到 "more",然后仔细查看其结果。





回页首


更多字符匹配

'[ ]' 规则表达式语法还有一些附加选项。要指定字符范围,只要字符不在第一个或最后一个位置,就可以使用 '-',如下所示:

 '[a-x]*' 

这将匹配零或多个全部为 '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 UnleashedSuSE linux UnleashedSamba Unleashed 的作者。Daniel 自小学二年级起就与计算机结下不解之缘,那时他首先接触的是 Logo 程序语言,并沉溺于 Pac-Man 游戏中。这也许就是他至今仍担任 SONY Electronic Publishing/ Psygnosis 的首席图形设计师的原因所在。Daniel 喜欢与妻子 Mary 和新出生的女儿 Hadassah 一起共度时光。可通过 drobbins@gentoo.org 与 Daniel 联系。


分享到:
评论

相关推荐

    sed awk讲解资料全集

    本资料全集将深入讲解这两个工具的使用,帮助你掌握它们的精髓,让你能够自如地完成各种字符串操作。 首先,让我们了解一下sed,全称为Stream Editor(流编辑器)。sed主要工作在输入流上,可以实时地对数据进行读...

    sed使用讲解,非常好,可以看看

    ### sed使用讲解 #### 一、sed简介与应用场景 sed(stream editor)是一种强大的文本处理工具,主要用于在命令行环境中对文件进行编辑操作。它能够高效地完成诸如查找、替换、删除、插入等任务,无需手动打开文件...

    sed 实例讲解

    ### sed 实例讲解 在Unix和类Unix系统中,sed(stream editor)是一个强大的文本处理工具,用于执行基本的文本转换工作。它读取输入流(可以是文件或标准输入),进行模式匹配和替换,然后将结果输出到标准输出。...

    Sed与awk_中英文高清版

    《Sed与Awk》是IT领域中关于文本处理的经典之作,主要讲解了两种强大的命令行工具:Sed(流编辑器)和Awk(数据处理语言)。这两款工具在Linux和Unix系统中广泛使用,尤其适用于数据提取、转换、报告生成等任务。 ...

    awk &sed program 2ed

    《awk & sed 程序设计第二版》是IT领域中一本重要的系统管理资源,它深入浅出地讲解了awk和sed这两个强大的文本处理工具。这两款工具在Linux和Unix环境中广泛使用,对于系统管理员和程序员来说,掌握它们的基础和...

    sed and awk 101 hacks

    第六章深入讲解了sed中的保持空间(HoldSpace)与模式空间(PatternSpace)的命令,这些命令允许sed在处理文本时存储和操作更多的数据: - 交换保持空间和模式空间(SwapPatternSpacewithHoldSpace,xcommand)。 - ...

    awk and sed 3

    3. **正则表达式**:详细讲解如何在`awk`和`sed`中使用正则表达式进行模式匹配。 4. **脚本实例**:提供各种实际应用场景的脚本示例,如日志分析、CSV数据处理、文本格式转换等。 5. **高级特性**:涵盖`awk`的...

    5.4: 正则表达式 、 sed基本用法 、 sed文本块处理.docx

    本文档主要讲解了正则表达式的基本用法和sed命令的应用,通过实际案例,详细介绍了正则表达式的匹配规则和sed命令的使用方法。 1. 正则表达式的基本用法 正则表达式是一种灵活的字符串匹配方式,广泛应用于 Unix/...

    Sed & Awk 2nd Edition

    第四章:讲解如何编写sed脚本,包括sed的工作原理和脚本编写技巧。 第五章:涵盖了基本的sed命令,包括对文件进行插入、删除和修改操作的命令。 第六章:介绍了高级的sed命令,帮助读者更加深入地掌握sed的高级...

    sed&awk101 Hacks

    sed多行模式及循环部分,讲解了sed处理多行文本的能力,包括读取下一行数据附加到模式空间的命令(N),打印多行模式中的第一行(P),删除多行模式中的第一行(D)等。 在awk部分,手册介绍了awk命令语法、程序...

    linuxsed与awk第三版

    这本书详细地讲解了这两个工具的使用方法和高级技巧,旨在帮助读者提升对文本处理的掌控能力。 Sed是一种流编辑器,它可以从标准输入读取数据,进行处理,然后将结果输出到标准输出。Sed的强大之处在于它可以对文本...

    Linux Shell脚本编程--sed命令详解.zip_shell sed_命令介绍_脚本 shell

    本文将深入讲解`sed`命令的基本概念、功能以及在Shell脚本中的具体应用。 `sed`是一种非交互式的文本处理工具,它可以从标准输入读取数据,对数据进行处理,然后将结果输出到标准输出。`sed`的强大之处在于它可以...

    Sed&Awk 2th Edition

    总之,《Sed&Awk 2th Edition》是学习这两个经典工具的必备资料,无论你是初学者还是有经验的用户,都能从中受益匪浅。通过深入阅读和实践,你将能够灵活运用Sed和Awk解决各种文本处理挑战,成为文本处理领域的专家...

    Sed与awk第二版(高清版)

    《Sed与Awk第二版》是一本深入探讨文本处理工具Sed和Awk的经典教程。这本书以高清的形式呈现,旨在帮助读者更好地理解和掌握这两种强大的命令行工具。Sed(Stream Editor)和Awk(Aho-Wedderburn-Kernighan)在Linux...

    sed与awk(第二版)

    3. **awk入门**:讲解awk的语法基础,包括字段分割、内置变量和函数。 4. **awk模式与动作**:深入理解awk的模式匹配和执行动作,以及如何定义自己的函数。 5. **awk控制流程**:介绍if-else、while、for等控制结构...

    一些sed命令

    压缩包内的`sed命令使用.docx`、`Sed命令学习笔记.pdf`、`sed使用手册.pdf`都是非常好的学习资料,它们将更深入地讲解sed命令的高级用法,包括模式匹配的细节、流编辑的技巧以及在实际工作中的应用案例。通过阅读...

    AWK教程(里面也有sed)

    接着是“sed与awk(第二版).pdf”,这本书是学习SED和AWK的经典之作。SED,全称Stream Editor,同样用于文本处理,但它通常用于对文本流进行行编辑,如替换、删除、插入等操作。这本书的第二版可能会深入讲解sed的...

    sed与awk+第三版和源代码

    在本书的第三版中,作者可能会详细讲解sed和awk的基本语法,包括正则表达式、模式空间、命令行选项等,并通过实例来展示如何使用这两个工具。同时,源代码文件(progs.tar.gz)很可能是书中各个例子的源代码集合,读者...

Global site tag (gtag.js) - Google Analytics