Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1350066
  • 博文数量: 112
  • 博客积分: 7112
  • 博客等级: 少将
  • 技术积分: 1299
  • 用 户 组: 普通用户
  • 注册时间: 2007-05-31 16:27
文章分类

全部博文(112)

文章存档

2011年(19)

2010年(20)

2009年(16)

2008年(20)

2007年(37)

分类: LINUX

2008-11-18 10:23:17

近来看到几个不是很常见,但是比较有用的sed例子,都和hold space与pattern space有关,
于是对几个例子做了自己认为正确的解释,贴出来与大家共享并请指正,继续讨论

例子一
sed G
在文件每一行下面输出一个空行

CODE:
$ cat foo
11111111111111
22222222222222
33333333333333
44444444444444
55555555555555

$ sed G foo
11111111111111

22222222222222

33333333333333

44444444444444

55555555555555

解释:

sed 中 G 的用法
The G function appends the contents of the holding area to the contents of
the pattern space. The former and new contents are separated by a newline. The
 maximum number of addresses is two.

hold space : 保持空间(或者叫保留空间、缓冲区),初始为空
pattern space :模式空间

在上面的例子中,将为空的hold space附加到文件的每一行后面,所以结果是每一行后面多了一个空行

引申出:
sed '/^$/d;G'
在文件的每一个非空行下面输出一个空行
sed '/^$/d;G;G'
在文件的每一个非空行下面输出两个空行

CODE:
$ cat foo
11111111111111
22222222222222

33333333333333
44444444444444
55555555555555

$ sed '/^$/d;G' foo
11111111111111

22222222222222

33333333333333

44444444444444

55555555555555

注:有时会有一些由空格符或者TAB组成的空行,前面的正则式 ^$ 就不能匹配到这样的行,则可以这样
    sed '/[[]]/d;G'


例子二
sed '/regex/{x;p;x;}'
在匹配regex的所有行前面插入一个空行

CODE:
$ cat foo
11111111111111
22222222222222
test33333333333333
44444444444444
55555555555555

$ sed '/test/{x;p;x;}' foo
11111111111111
22222222222222

test33333333333333
44444444444444
55555555555555

解释:
sed 中 x 的用法
The exchange function interchanges the contents of the pattern space and the
holding area. The maximum number of addresses is two.
即交换保持空间hold space和模式空间pattern space的内容

sed 中 p 的作用是把模式空间复制到标准输出。

分析一下该命令执行过程中保持空间和模式空间的内容

命令      保持空间                             模式空间
x     执行前:null   执行后:test\n         执行前:test\n 执行后:null
p     执行前:null   执行后:test\n         执行前:test\n 执行后:null       输出一个空行
x     执行前:test\n 执行后:null           执行前:null   执行后:test\n

(注:把test所在的行简写为test了)

引申:
可以试验一下 sed '/test/{x;p;}' foo  或者 sed '/test/{p;x;}' foo 等,看看结果,体会两
个空间的变化

相应的:
sed '/regex/G'  是在匹配regex的所有行下面输出一个空行
sed '/regex/{x;p;x;G;}' 是在匹配regex的所有行前面和下面都输出一个空行


例子三
sed 'n;G;'
在文件的偶数行下面插入一个空行

CODE:
$ cat foo
11111111111111
22222222222222
33333333333333
44444444444444
55555555555555

$ sed 'n;G;' foo
11111111111111
22222222222222

33333333333333
44444444444444

55555555555555

解释:
sed 中 n 的用法:将模式空间拷贝于标准输出。用输入的下一行替换模式空间。

执行 n 以后将第一行输出到标准输出以后,然后第二行进入模式空间,根据前面对 G 的解释,
会在第二行后面插入一个空行,然后输出;再执行 n 将第三行输出到标准输出,然后第四行进入模式空间
,并插入空行,依此类推

相应的:
sed 'n;n;G'     表示在文件的第 3,6,9,12,... 行后面插入一个空行
sed 'n;n;n;G'   表示在文件的第 4,8,12,16,... 行后面插入一个空行
sed 'n;d'       表示删除文件的偶数行


例子四
sed '$!N;$!D'   
输出文件最后2行,相当于 tail -2 foo

CODE:
$ cat foo
11111111111111
22222222222222
33333333333333
44444444444444
55555555555555

$ sed '$!N;$!D' foo
44444444444444
55555555555555

解释:

D 删除模式空间内第一个 newline 字母 \n 前的资料。
N 把输入的下一行添加到模式空间中。

sed '$!N;$!D' : 对文件倒数第二行以前的行来说,N 将当前行的下一行放到模式空间中以后,D 就将模式空间的内容删除了;到倒数第二行的时候,将最后一行附加到倒数第二行下面,然后最后一行不执行 D ,所以文件的最后两行都保存下来了。


还有 N 的另外一种用法

CODE:
$ sed = foo | sed N
1
11111111111111
2
22222222222222
3
33333333333333
4
44444444444444
5
55555555555555

$ sed = foo | sed 'N;s/\n/        /'
1       11111111111111
2       22222222222222
3       33333333333333
4       44444444444444
5       55555555555555

解释:
N 的作用是加上行号,可以用于格式化输出文件


例子五
sed '1!G;h;$!d'
sed -n '1!G;h;$p'         
将文件的行反序显示,相当于 tac 命令(有些平台没有这个命令)

CODE:
$ cat foo
11111111111111
22222222222222
33333333333333

$ sed '1!G;h;$!d' foo
33333333333333
22222222222222
11111111111111

$ sed -n '1!G;h;$p' foo
33333333333333
22222222222222
11111111111111

解释:
sed 中 h 用法:h
The h (hold) function copies the contents of the pattern space into a holding area, destroying any previous contents of the holding area.
意思是将模式空间的内容保存到保持空间中去

sed 中的 d 表示删除模式空间。

1!G表示除了第一行以外,其余行都执行G命令;$!d表示除了最后一行以外,其余行都执行d命令。

看一下sed '1!G;h;$!d'命令执行过程中保持空间与模式空间的变化:

        命令                 保持空间                             模式空间
第一行  h;d     执行前:null        执行后:1111\n                执行前:1111\n 执行后:null
第二行  G;h;d   执行前:1111        执行后:2222\n1111\n          执行前:2222\n 执行后:null         
第二行  G;h     执行前:2222\1111\n 执行后:3333\n2222\n\1111\n   执行前:3333\n 执行后:3333\n2222\n\1111\n

(注:把各个行简写了)

这样输出以后就是文件的反序了。

题外话:在vi中对一个文件进行反序显示的命令是 :g/./m0 , 意思是按照文件正常顺序每找到一行,就把该行放到文件的最上面一行去,这样循环一下正好把文件的行反序显示了。
==================================================================================
# print the last 10 lines of a file (emulates "tail")
#打印一个文件的后10行(仿"tail")
sed -e :a -e '$q;N;11,$D;ba'

试着注一下,不知道对不对

如果我们只看sed -e :a -e '$q;N;ba'
这个循环不停的读入下 一行直到结尾,这样整个文本就形成一个由\n分割的链

现在加上11,$D
sed -e :a -e '$q;N;11,$D;ba'
如果文本不超过10行
模式空间将保留整个文本打印出来
如果文本大于10行
从第11行开始,在下一行加入到链中后,模式空间第一个由\n分割的记录将被删除,这样看起来就是链头被链尾挤出整个链,总是保持10个链环,循环结束后,链中保存的就是文件的后10行,最后印出结果

==========================================================================
[root@orzz cwm]# more tt.txt
[A][B]
        Path No:       [Network]
        Path No:       [Memory]
[A][C]
        Data Da:       [Process]
        Data Da:       [CPU]
[root@orzz cwm]# sed -r '/^\[/{h;d};G;s/.* ([^ ]+)\n(.*)/sm \2\1 -n \1/' tt.txt
sm [A][B][Network] -n [Network]
sm [A][B][Memory] -n [Memory]
sm [A][C][Process] -n [Process]
sm [A][C][CPU] -n [CPU]

用awk解决如下:
[root@orzz cwm]# awk '/^\[/{a=$0;next}{print "sm "a""$3" -n "$3}' tt.txt
sm [A][B][Network] -n [Network]
sm [A][B][Memory] -n [Memory]
sm [A][C][Process] -n [Process]
sm [A][C][CPU] -n [CPU]
[root@orzz cwm]#


=====================================================
原文件如下:
select abc form dbs where a=b and b=c
select abc
form dbs
where
a=b and b=c
select
dbs
where
a=b
and
b=c
select * from dbs where a-b

要删除包含where a=b and b=c的行(也就是删除红字的行),但有可能是二行或是三行组成的。
结果如下:
select abc
form dbs
select
dbs
select * from dbs where a-b

因为包含的内容行数不固定用awk处理起来比较难,不知道sed可不可以处理,谢谢了!


sed '/where/{:a;s/[ \n]*where[ \n]*a=b[ \n]*and[ \n]*b=c//;tb;/\nwhere/{P;D;};N;ba;:b;d}' urfile


:a  冒号用来定义标签,名字可以自定义。:a定义标签a,用于指令跳转,循环处理。
tb t命令会在s///成功后跳到b标签;失败则不跳转,继续后面的指令。省略标签时,跳到脚本末尾,亦即开始处理下一行
ba 是无条件跳转到标签a。省略标签a则到脚本末尾。


提取 之间的内容
[root@gfs1 ~]# more 1.txt
dffcwm

aaa
bbb
ccccc

dff
chen

fff

dfff
cwm
[root@gfs1 ~]# sed -n '//{:a;s/\n\(.*[^>]\)\n<\/d>/\1/g;tc;N;ba;:c;p}' 1.txt
aaa
bbb
ccccc
fff

阅读(4189) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~