Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3020546
  • 博文数量: 272
  • 博客积分: 5544
  • 博客等级: 大校
  • 技术积分: 5496
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-08 00:48
个人简介

  每个人都要有一个骨灰级的爱好,不为金钱,而纯粹是为了在这个领域享受追寻真理的快乐。

文章分类

全部博文(272)

文章存档

2015年(2)

2014年(5)

2013年(25)

2012年(58)

2011年(182)

分类: LINUX

2011-11-07 00:25:19

文本:
sad
asd
startpoint:xxxxxx
endpoint:xxxxx
path:xxxx
slack:xxxx
jccj
path:xxxx
zi
startpoint:xxxxxx
endpoint:xxxxx
要求把含有冒号的连续的多行合并成一行,以空格分割:
sad
asd
startpoint:xxxxxx endpoint:xxxxx path:xxxx slack:xxxx
jccj
path:xxxx
zi
startpoint:xxxxxx endpoint:xxxxx



  1. sed '/:/{:a;N;/\n[^:]*$/!{$!ba};s/\n\([^:]*:\)/ \1/g}' file
[解析]
一开始这问题还有点小棘手,思考再三定下觉得正确的思路后慢慢写,最后还是搞定了。把匹配到冒号的行开始执行死循环,一直用 N 读取下一行,直到读到没有冒号的行,或者读到尾行,才开始替换,把换行替换成空格,这样跳出死循环后,命令执行完了sed会把结果输出。这是总体的思路,细节上几个注意的地方,第一:匹配不包含冒号的行,注意后面加上 $ 边界,表示文本末尾,否则的话前面 pattern space 内的内容也匹配到,sed就会去执行替换,从而失败。第二,如果只是全局替换\n为空格,那么会把最后那行不包含冒号的行也会被替换到同一行内,所以这里要排除最后一个 \n 后不包含冒号内容。第三,用N读取到最后一行,发现没匹配到冒号它又会再次死循环ba跳去N读取下一行,发现没有行可以读取的时候N会中止命令直接结束,那么就不会有后面的替换操作,为了避免这种情况,必须加上尾行的判断,把ba跳转排除尾行。

  1. sed '/:/{:a;N;/:[^\n]*$/s/\n/ /;ta;P;D}' file
[解析]
这个命令就要短很多了,我老是忘了我们的老朋友,P;D 组合。匹配到冒号的行后,N读取下一样内容,然后尝试替换,如果下一行也是有冒号的行,那么冒号后面到 $ 结束就不会有换行符,替换会成功,ta 跳转去Table a处,又读取下一行,直到读取到不含有冒号的行,那么匹配就会失败,因为该行不含有冒号,正则会匹配到上一行的冒号,那样的话后面必然会出现一个换行符了,所以替换失败,ta不会生效,这时候执行后面的 P 打印 pattern space 的第一行,也就是把含有冒号的行处理为了一整行的那一行,然后 D 删除 pattern space 的第一行。这时候  pattern space 留下的是 "jccj" 这样的内容,那么 D 会跳转命令去行首继续执行,这时候不匹配冒号 "jccj" 就被输出到了屏幕,然后继续后面的操作。





  1. awk '/:/{i=i?i FS $0:$0;next}{print i?i RS $0:$0;i=0}END{if(i)print i}' file
[解析]
其实awk执行流程更符合我们的编程思维,匹配到冒号的行,就把各行用 FS 空格接起来,直到没有匹配到冒号然后打印出来,并把i变量置零。最后END再判断一下,如果i有内容就打印。

  1. awk 'ORS=/:/?FS:RS;END{printf RS}' file
[解析]
这个就不说了,秒杀。

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