linux sed高级用法,Sed高级用法

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的会打印出hell,MM;其他的一概不打印。

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

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

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

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

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

> /@fl(.*/{

> N

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

> }' expl.6

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

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

3.:,b,t的用法

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

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

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

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

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

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

为是标签的一部分。

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

[address]b[label]

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

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

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

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

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

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

(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

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

[address]t[label]

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

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

s/pattern/replacement/

t break

command

:break

还是用例6的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.H,h,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/匹配的行上进行替换。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值