`
saybody
  • 浏览: 869420 次
  • 性别: 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和awk吗, 被别人复杂的sed和awk神奇和高效惊叹了吗,想知道其中的原因吗, 这里我搜集了讲解sed和awk全面的资料,让你自如的完成想要的操作,字符串的操作没有你办不到

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

    sed使用PDF文档,非常详细的文档,大家可以看看,适合新手老手。

    sed 实例讲解

    shell sed study example

    sed简明教程.pdf

    linux sed简明教程,通过最简单的案例,直观简洁的体验sed的神奇,讲解透彻,由浅入深,不知不觉掌握sed心法

    ASPAC-SED.rar_sed

    SED是UNIX环境下常用的工具之一.本文讲解如何使用SED进行文本处理与操作.

    sed命令格式解析.docx

    本文详细讲解了Linux shell编程三剑客之一的sed的用法,并给出了详细的例子。

    sed流编辑器的用法

    详细讲解了sed流编辑器的用法(包括sed的各种参数以及sed脚本文件的编写)。

    LINUX_sed_使用

    LINUX_sed_使用,详细讲解set命令的参数 举例说明 很不错的,哈哈

    sed_awk正则表达式

    了解sed awk 的不错资料,讲解的比较详细,希望对大家有用!

    sed与awk.zip

    详细讲解了linux下高级开关,包括sed命令的使用,awk命令的使用

    ibm sed和awk(中文高清版).pdf

    ibm sed和awk(中文高清版),IBM技术网站上讲解了awk和sed工具的语法以及样例,学习awk和sed的好资料。

    Python 实现简单的shell sed替换功能(实例讲解)

    下面小编就为大家带来一篇Python 实现简单的shell sed替换功能(实例讲解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    sed与awk 中文第二版.pdf

    非常经典的讲解Shell脚本的书籍。不过建议有一些Shell基础的读者来学习。

    Shell编程高级进阶系列视频.zip

    15Shell编程之函数及脚本案例讲解 16Shell编程之函数及脚本案例讲解 17Linux下Shell编程FIND、SED命令实战 18Linux下Shell编程FIND、SED命令实战 19Shell编程之awk、sed演练 20Shell编程之awk、sed演练( 21Shell编程...

    Linux三剑客命令从入门到放弃

    Linux三剑客命令从入门到放弃,详细讲解了awk,sed,grep三个命令的入门

    老男孩老师-Linux正则表达式实战 学习笔记

    根据老男孩老师视频教程《Linux正则表达式实战》的精彩讲解,进行了学习笔记记录,主要讲解Linux三剑客中的grep用法、捎带sed的讲解笔记。 学习笔记进行了规整,相信Linux运维工作者能够一目了然笔记的内容。 (1...

    实用详细的正则表达式讲解

    在计算机科学中,是指一个用来描述或者匹配一系列...正则表达式这个概念最初是由Unix中的工具软件(例如sed和grep)普及开的。正则表达式通常缩写成“regex”,单数有regexp、regex,复数有regexps、regexes、regexen。

    Linux下Shell编程从入门到精通视频教程.txt

    20、Shell编程之学习心得分享及拓展.mp4 19、Shell编程之实战WEB界面展示二.mp4 ...11、Shell编程之SED及GREP综合讲解.mp4 10、Linux下深入编程之函数及数组编程.mp4 09、Shell编程之函数及案例分析.mp4 08、She

    最有用Linux系列-百页精华.pdf(最易懂的方式,100页讲解常用命令工具)

    为了方便大家阅读,尤其是离线阅读。xjjdog将2019年公众号上最热门流行的文章中,找了100页,做成了电子书。 其中,《Linux上,最常用的一批命令解析(10年精选)》这篇文章,在CSDN发布首日,即收获1000+赞。...

Global site tag (gtag.js) - Google Analytics