Chinaunix首页 | 论坛 | 博客
  • 博客访问: 185825
  • 博文数量: 40
  • 博客积分: 2576
  • 博客等级: 少校
  • 技术积分: 494
  • 用 户 组: 普通用户
  • 注册时间: 2010-11-14 17:19
文章分类

全部博文(40)

文章存档

2011年(21)

2010年(19)

我的朋友

分类: LINUX

2010-11-22 18:40:40

Sed高级用法

1. Sed脚本的处理过程:

  Sed有一个模式空间这个名词,sed默认是一行一行的将文件读入到模式空间里的,然后对模式空间里的内容进行命令和匹配操作;

  默认的从模式空间出来的内容是打印到屏幕上的,但用-n-quiet可以屏蔽这个功能。

举例说明:

  Sed -n  '/alibaba/,/fuck/{w tao.txt;/girl/i\hello,MM;d} tao

  1) 首先将匹配地址地位到/alibaba/,/fuck/,如果没有/fuck/则匹配到文件尾;

  2)然后按行读入第一行/alibaba/到模式空间里,然后依照顺序执行脚本里的命令。

  3)再依次往下读,一行一行的读入到模式空间了,进行处理。

  4)处理结果是,在tao.txt中写入了从/alibaba//fuck/的行,如果有匹配girl的会打印出hellMM;其他的一概不打印。

2. 多行模式里三个命令N,D,P

 多行处理的命令常用的就这三个,估计就这三个,如果还有请留言,同学习。

 N:类似n,只不过-n在处理的时候是用下一行来替换模式空间里的内容;而-N是将下一行追加到模式空间里面。

 D:类似d-d删除的是模式空间里的所有内容,而D删除的是模式空间里的第一行,即当用N命令读入下一行进入模式空间的时候用D命令只会删除第一行。

 P:类似p,从上诉的介绍应该可以猜测出P的作用了,对,就是打印模式空间的第一行内容。

 举例说明下:

 root@localhost:~/test#sed -n '/it/{N;p}' tao 

  it is john ,bigjohn!

  alibaba 

 root@localhost:~/test#sed -n '/it/{N;P}' tao 

  it is john ,bigjohn!

root@localhost:~/test#sed  '/it/{N;s/john!\nalibaba/good alibaba\ndd/;}' tao 

  it is john ,biggood alibaba

  dd

从书上看到一个用NDP建立一个输入/输出循环的例子:

Sed  ' /Unix/{

N

s/\nSystem/Operating &/

P

D

}' exp5

#Cat exp5

Here are examples of the UNIX

System. Where UNIX

System appears, it should be the UNIX

Operating System.

 脚本执行后:

 root@localhost:~/test#sed '/UNIX/{

N

s/\nSystem/ Operating &/

P

D

}' exp5

Here are examples of the UNIX Operating 

System. Where UNIX Operating 

System appears, it should be the UNIX

Operating System.

解释:这个脚本用于维护两行的模式空间,但一次只输出一行。这个循环的目的是输出模式空间的第一行,然后返回到脚本的顶端将所有的命令应用于模式空间的第二行。

网上看到这样一个例子,挺能说明问题的:

 $ cat expl.6

    I want to see @fl(what will happen) if we put the

font change commands @fl(on a set of lines). If I understand

things (correctly), the @fl(third) line causes problems. (No?).

Is this really the case, or is it (maybe) just something else?

Let's test having two on a line @fl(here) and @fl(there) as

well as one that begins on one line and ends @fl(somewhere

on another line). What if @fl(it is here) on the line?

Another @fl(one).

现在要作的就是将"fl@(…)替换为"\fB(…)\fR。以下就是满足条件的sed 命令:

sed 's/@fl(\([^)]*\))/\\fB\1\\fR/g

> /@fl(.*/{

> N

> s/@fl(\(.*\n[^)]*\))/\\fB\1\\fR/g

> P

> D

> }' expl.6

然而,如果不使用这种输入输出循环,而是单单用来实现的话,就会出现问题:

sed 's/@fl(\([^)]*\))/\\fB\1\\fR/g

> /@fl(.*/{

> N

> s/@fl(\(.*\n[^)]*\))/\\fB\1\\fR/g

> }' expl.6

这样的sed 脚本是有漏洞的。

解释:其实这个很简单啦,第二个错误的是因为,在N之后加入的行,没有进行脚本命   令从头开始的处理。

3.:bt的用法

     这个借鉴网上的一个很好的说明:

     为了使使用者在书写sed 脚本的时候真正的"自由"sed 还允许在脚本中用":"设置记号,然

后用"b""t"命令进行流程控制。顾名思义,"b"表 示"branch""t"表示"test";前者就是分

支命令,后者则是测试命令。

首先来看标签的各式是什么。这个标签放置在你希望流程所开始的地方,单独放一行,以冒

号开始。冒号与变迁之间不允许有空格或者制表符,标签最后如果有空格 的话,也会被认

为是标签的一部分。

再来说命令。它的格式是这样的:

[address]b[label]

它的含意是,如果满足address,则sed 流程跟随标签跳转:如果标签指明的话,脚本首先

假设这个标签在命令以下的某行,然后转入该行执行相应的命 令;如果这个标签不存在

的话,控制流程就直接跳到脚本的末尾。否则继续执行后续的命令。

在某些情况下,命令和!命令有些相似,但是!命令只能对紧挨它的{}中的内容起作用,而

命令则给予使用者足够的自由在sed 脚本中选择哪些命令应该被 执行,哪些命令不应该

被执行。下面提供几种命令的经典用法:

(1) 创建循环:

:top

command1

command2

/pattern/b top

command3

(2) 忽略某些不满足条件的命令:

command1

/patern/b end

command2

:end

command3

(3) 命令的两个部分只能执行其中一个:

command1

/pattern/b dothere

command

b

:dothere

command3

命令的格式和命令是一样的:

[address]t[label]

它表示的是如果满足address 的话,sed 脚本就会根据命令指示的标签进行流程转移。而标

签的规则和上面讲的命令的规则是一样的。下面也给出一个 例子:

s/pattern/replacement/

t break

command

:break

还是用例sed 脚本为例子。其实仔细思考一下就会发现这个脚本不是足够强大:如果某

@fl 结构跨越了两行,比如说三行怎么办?这就需要下面这个加强 版的sed 了:

$ cat expl.6.sed

:begin

/@fl(\([^)]*\))/{

s//\\fB\1\\fR/g

b begin

}

/@fl(.*/{

N

s/@f1(\([^)]*\n[^)]*\))/\\fB\1\\fR/g

t again

b begin

}

:again

P

D

4.Hh,g,G,y这个在基本用法中已做介绍了,举个例子吧:

 root@localhost:~/test#cat tao

alibaba ff

alibaba

this is a test file

-tao shou kun has a english na

it is john ,bigjohn!

alibaba

companytao

Now

root@localhost:~/test#sed '

/ff/{

h

d

}

/alibaba/{

G

}

' tao

处理后就是将第一行复制到/alibaba/匹配的行后面。用g的话是在/alibaba/匹配的行上进行替换。

阅读(2259) | 评论(3) | 转发(0) |
0

上一篇:sed基本用法总结

下一篇:linux exec用法总结

给主人留下些什么吧!~~

mutoumint2013-12-26 14:12:58

你这第一个例子就失败了

[root@m1 ~]# cat tao
1
alibaba
fuck
4
[root@m1 ~]# sed -n  '/alibaba/,/fuck/{w tao.txt;/girl/i\hello,MM;d}' tao

sed: 无法打开文件 tao.txt;/girl/i\hello,MM;d}: 没有那个文件或目录

chinaunix网友2010-11-26 16:35:58

不错!

chinaunix网友2010-11-23 14:44:58

很好的, 收藏了 推荐一个博客,提供很多免费软件编程电子书下载: http://free-ebooks.appspot.com