Chinaunix首页 | 论坛 | 博客
  • 博客访问: 102851
  • 博文数量: 31
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 0
  • 用 户 组: 普通用户
  • 注册时间: 2013-06-05 21:27
文章分类
文章存档

2014年(24)

2013年(7)

分类: LINUX

2014-07-22 21:20:06

很久没更新了, 对不起访问我博客的网友们, I will be back.
今天在论坛看到一篇有点意思的题目, 跟大家分享一下.

cat file
clone=line1
gb=line1
gi=line1
lib=line1
gb=line2
gi=line2
lib=line2
clone=line3
gb=line3
gi=line3
lib=line3
gb=line4
gi=line4
lib=line4

期望结果(注意clone这一行可能会没有):
lib=line1 gi=line1 gb=line1 clone=line1 
lib=line2 gi=line2 gb=line2
lib=line3 gi=line3 gb=line3 clone=line3
lib=line4 gi=line4 gb=line4



  1. sed -n 'G;/^lib/{s/\n/ /gp;n};h' file
[解析]
    其实就是一个多行合并为一行的问题, 仔细看看, 可以理解为当读取到lib关键字的时候倒序排列成一行, 这里我们利用G这个函数, 其目的就是把hold space里的内容追加到当前pattern中, 第一行时G追加hold space里的内容到pattern space后, 中间用'\n'连接, 当时hold space里没有内容, 其实就是添加了一个换行符而已, 然后继续执行命令, 没有匹配到lib关键字, 不执行花括号里的操作, 执行h函数操作, 把当前行的内容(就是第一行的内容后面多加了一个换行符)覆盖到hold space里, 第二行时执行G函数, 这时候pattern space里的内容已经变成了gb=line1\nclone=line1, 这时候也没有匹配到lib, 那么继续执行h, 这样就相当于倒序排列了内容. 执行到第四行, 匹配到lib时候, 我们把所有的换行符替换为空格, 并且打印内容, 执行n操作, 把stream执行到下一行, 用下一行的内容来覆盖hold space里的内容, 这样就相当于清楚了之前hold space里的记录.


  1. sed -r ':1;N;s/(.*)\n(.*)/\2 \1/;/lib/!b1' file
[解析]
    其实这是最容易理解的, 就是不停读取下一行, 然后交换上下行的位置, 达到倒序排列的目的. 当匹配到lib行的时候, 就跳出循环, 默认输出pattern space里的内容.


  1. awk '{s=s?$1" "s:$1}/^lib/{print s;s=""}' file
[解析]
    其实awk的思路也是一样的, 只是工具不同而已, 也是把当行添加到变量s后面, 直线倒序排列, 最后匹配到lib关键字的时候就输出内容, 并清空变量s.



  1. awk '{a[++l]=$1}/^lib/{for(i=l;i>1;i--){printf a[i]" "}print a[i];l=0}' file
[解析]
    还有我们的数组老朋友, 话说awk的关联数组那真心是比C例的索引数组强太多了, 好好利用这个神器.



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