LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1493|回复: 10

sed 练习:sed对于段落的处理.

[复制链接]
发表于 2004-12-21 13:02:58 | 显示全部楼层 |阅读模式
练习文件:
----------------------------------------
a~1234
xxxxx
bbbbb
ooooo
DONE

a~5678
xxxxxx
ffffffff
kkkkkkk
mmmmmmm
NONDONE

a~112334
kdjfiels
dfjldkdeee
dkccke
skdjfieiw
11
DONE

a~11234
pppooeif
kkkdekde
gnome
helloworld
hihihihi
ohohohoh
DONE

a~!3324
ksdjofe-
lskdjfi,skddjie
kill:pid
NONDONE

a~3325
knoppix
gnoppix
santa fa
quake3d
goodgood
successful!!!
DONE
------------------------------------------
要求:
1. 只能用sed.
2. 输出结果: 只显示"NONDONE"的段落块或"DONE"的段落块.
3. 可以pipe sed 命令, 但不许用其他任何命令.
我搞了半天才搞出来, 发现这是一个对于一些高级sed命令很好的练习. 故抽象后拿出来给大家试试. 看看我们能有多少中方法.
发表于 2004-12-21 14:03:11 | 显示全部楼层
你这个文件里头好象每个段都有,不用处理的

顺便问个问题:在计算机里面,怎么判断文章的段? :thank
 楼主| 发表于 2004-12-21 14:10:49 | 显示全部楼层
看清楚了, 不是每个段都有阿. 有些有"NONDONE" 有些有"DONE". 要求是只输出有"NONDONE"或是"DONE"的段.
发表于 2004-12-21 15:01:46 | 显示全部楼层
  1. sed -n -f para.sed test2
复制代码

para.sed如下
  1. /^$/b aa
  2. H
  3. d
  4. :aa
  5. x
  6. /\ndone$/p
复制代码
发表于 2004-12-21 19:20:24 | 显示全部楼层
超级恐怖 :eek:
[php]
[linux_now@linux_power test]$ cat test.txt | sed  '1!G;h;$!d' | \
sed -n -e '/^DONE$/b done;/^NONDONE$/b nondone; b end;:done;p;n;/^NONDONE$/b nondone;b done;:nondone;/^DONE$/b done;n;b nondone;:end' | \
sed  '1!G;h;$!d'
[/php]

  1. a~1234
  2. xxxxx
  3. bbbbb
  4. ooooo
  5. DONE

  6. a~112334
  7. kdjfiels
  8. dfjldkdeee
  9. dkccke
  10. skdjfieiw
  11. 11
  12. DONE

  13. a~11234
  14. pppooeif
  15. kkkdekde
  16. gnome
  17. helloworld
  18. hihihihi
  19. ohohohoh
  20. DONE
  21.                                                                                 
  22. a~3325
  23. knoppix
  24. gnoppix
  25. santa fa
  26. quake3d
  27. goodgood
  28. successful!!!
  29. DONE
复制代码

  1. [linux_now@linux_power test]$ cat test.txt \
  2. | sed  '1!G;h;$!d'|sed -n -e '/^DONE$/b done;/^NONDONE$/b nondone; b end;:done;n;/^NONDONE$/b nondone;b done;:nondone;/^DONE$/b done;p;n;b nondone;:end' \
  3. | sed  '1!G;h;$!d'

  4. a~5678
  5. xxxxxx
  6. ffffffff
  7. kkkkkkk
  8. mmmmmmm
  9. NONDONE

  10. a~!3324
  11. ksdjofe-
  12. lskdjfi,skddjie
  13. kill:pid
  14. NONDONE

复制代码
 楼主| 发表于 2004-12-21 21:44:30 | 显示全部楼层
哇, 是挺长的... ;-)
 楼主| 发表于 2004-12-22 11:34:05 | 显示全部楼层
我的是这样的:

  1. sed -n '/\<DONE\>/{n;h;b};/\<NONDONE\>/{H;x;p;n;x;b};H'
复制代码
发表于 2007-12-17 02:38:44 | 显示全部楼层
老贴翻新一下
/^$/b done
$ b done
1h;1!H;d
:done
x;/\<DONE\>/!d;
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-12-18 15:59:30 | 显示全部楼层
Post by ArchieYao;1796523
老贴翻新一下
/^$/b done
$ b done
1h;1!H;d
:done
x;/\<DONE\>/!d;


不错。利用了branch的功能。不过有些小问题。最后一个DONE没有了。考虑一下。
回复 支持 反对

使用道具 举报

发表于 2007-12-18 19:08:49 | 显示全部楼层

  1. sed ':a;N;/DONE$/!ba;/\nDONE/d'  这个将输出有NONDONE的字段

  2. sed ':a;N;/DONE$/!ba;/\nNONDONE/d' 这个将输出只有DONE的字段

复制代码


解释:
依据是分析上面的段落结构,每段的最后一行是DONE或者NONDONE


[color="Magenta"]原来的解释反了,经yongjian提醒,特更正
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表