免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: rm-rf
打印 上一主题 下一主题

[文本处理] 求助: sed取匹配行前面的第3行,然后结束匹配 [复制链接]

论坛徽章:
2
技术图书徽章
日期:2013-12-17 13:52:152015亚冠之萨济拖拉机
日期:2015-07-19 11:07:52
11 [报告]
发表于 2015-07-12 19:39 |只看该作者
回复 9# WilliBhamlll


大师,我对sed完全不懂,查手册看帖子搞了一下午,打算一次读3行,用D来删除匹配空间的第1行,然后打印,不过最终失败了。

请教您的这个脚本:
$ sed -nr '/begin/{x;s/.* (.*)(.*\n){2}.*/\1/p;Q};H' file

它的确管用,不过能详细解释一下么?小弟拜谢了。


论坛徽章:
0
12 [报告]
发表于 2015-07-13 13:46 |只看该作者
grep -B 3 'begin' data5 | head -n 1 | awk '{print $2}'

论坛徽章:
11
射手座
日期:2015-08-11 16:10:26辰龙
日期:2015-08-11 16:11:11黑曼巴
日期:2016-04-26 16:58:40
13 [报告]
发表于 2015-07-13 16:03 |只看该作者
本帖最后由 hjfeng1988 于 2015-07-13 16:59 编辑

回复 10# 聆雨淋夜

回复 11# rm-rf
  1. sed -nr '/begin/{x;s/.* (.*)(.*\n){2}.*/\1/p;Q};H' file
复制代码
没匹配begin,执行H添加模式空间至保留空间
a 1\nv 56\ndf8 2\nj5i 65
匹配begin,执行x交换模式空间与保留空间,
(.*\n){2}匹配到\ndf8 2\n,此处因为前方的(.*)匹配了56,所以不是匹配56\ndf8 2\n或者更长的;
往前的(.*)匹配到56
再往前的.* 匹配到a 1\nv (注意空格);
将前文匹配的内容替换为\1,代表第一次出现在()中的内容,p打印,Q退出。
  1. sed -nr '/begin/{x;s/.* (.*)(\n.*){2}/\1/p;q};H' file
复制代码
感觉改成这样更清晰

论坛徽章:
2
技术图书徽章
日期:2013-12-17 13:52:152015亚冠之萨济拖拉机
日期:2015-07-19 11:07:52
14 [报告]
发表于 2015-07-13 16:24 |只看该作者
回复 13# hjfeng1988

原来是这样。

我今天在生产环境跑了一下,发现问题了,有些文件并不是两列的格式,有些文件的列数是不固定的,不过匹配标准仍然不变:

找到第1次匹配的以begin开头的行,然后打印出匹配行前面的第3行的第2列,然后结束匹配,剩下的begin不再过滤。

a 1
v 56 999 4567
df8 2 kkk lll kkk
j5i 65 j
begin 456 ggh
75 df
ghi -5
74 op
begin dfg


这样的话,sed还能搞么?感谢。
   

论坛徽章:
11
射手座
日期:2015-08-11 16:10:26辰龙
日期:2015-08-11 16:11:11黑曼巴
日期:2016-04-26 16:58:40
15 [报告]
发表于 2015-07-13 16:43 |只看该作者
本帖最后由 hjfeng1988 于 2015-07-13 16:44 编辑
  1. sed -nr '/begin/{x;s/.*\n[^ ]* ([^ ]*) .*(\n.*){2}/\1/p;Q};H' file
复制代码
不是说了要效率么,这种sed写法没效率吧。测试有问题,这个不行

用680的awk写法

论坛徽章:
3
水瓶座
日期:2014-03-25 17:08:042015亚冠之塔什干棉农
日期:2015-08-10 10:45:122015亚冠之萨济拖拉机
日期:2015-08-13 16:05:24
16 [报告]
发表于 2015-07-13 16:53 |只看该作者
回复 1# rm-rf


    sed '/^begin/q' 9 | awk 'NR==3{print $2}'
2

这样可以不

论坛徽章:
23
15-16赛季CBA联赛之吉林
日期:2017-12-21 16:39:27白羊座
日期:2014-10-27 11:14:37申猴
日期:2014-10-23 08:36:23金牛座
日期:2014-09-30 08:26:49午马
日期:2014-09-29 09:40:16射手座
日期:2014-11-25 08:56:112015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:0315-16赛季CBA联赛之山东
日期:2017-12-21 16:39:1915-16赛季CBA联赛之广东
日期:2016-01-19 13:33:372015亚冠之山东鲁能
日期:2015-10-13 09:39:062015亚冠之西悉尼流浪者
日期:2015-09-21 08:27:57
17 [报告]
发表于 2015-07-13 16:59 |只看该作者
本帖最后由 ly5066113 于 2015-07-13 17:45 编辑

回复 14# rm-rf


try:
  1. sed -r '1{N;N};N;/\nbegin/{s/^[^ ]* ([^ ]+).*/\1/;q};D' file
复制代码

论坛徽章:
780
金牛座
日期:2014-02-26 17:49:58水瓶座
日期:2014-02-26 18:10:15白羊座
日期:2014-04-15 19:29:52寅虎
日期:2014-04-17 19:43:21酉鸡
日期:2014-04-19 21:24:10子鼠
日期:2014-04-22 13:55:24卯兔
日期:2014-04-22 14:20:58亥猪
日期:2014-04-22 16:13:09狮子座
日期:2014-05-05 22:31:17摩羯座
日期:2014-05-06 10:32:53处女座
日期:2014-05-12 09:23:11子鼠
日期:2014-05-21 18:21:27
18 [报告]
发表于 2015-07-13 17:26 |只看该作者
回复 1# rm-rf

可以考虑用grep的话这样做效率不差的吧.
  1. grep -m1 -B3 "^begin" i|awk '{print $2;exit}'
  2. 56
复制代码

论坛徽章:
22
处女座
日期:2014-10-11 13:33:292015亚冠之塔什干火车头
日期:2015-07-20 19:59:042015亚冠之塔什干火车头
日期:2015-07-26 10:59:31程序设计版块每日发帖之星
日期:2015-08-05 06:20:00每日论坛发贴之星
日期:2015-08-05 06:20:00程序设计版块每日发帖之星
日期:2015-08-07 06:20:00每日论坛发贴之星
日期:2015-08-07 06:20:002015亚冠之阿尔纳斯尔
日期:2015-10-01 15:23:28白银圣斗士
日期:2015-12-07 17:17:06操作系统版块每日发帖之星
日期:2015-12-27 06:20:002015亚冠之广州富力
日期:2015-07-08 15:48:31程序设计版块每日发帖之星
日期:2015-06-11 22:20:00
19 [报告]
发表于 2015-07-13 17:29 |只看该作者
回复 13# hjfeng1988
我的疑问如下
交换后,模式空间的内容如下:
a 1\nv 56\ndf8 2\nj5i 65

为什么(.*\n){2}匹配到\ndf8 2\n      而不是匹配  a 1\nv 56\n


   

论坛徽章:
11
射手座
日期:2015-08-11 16:10:26辰龙
日期:2015-08-11 16:11:11黑曼巴
日期:2016-04-26 16:58:40
20 [报告]
发表于 2015-07-13 17:37 |只看该作者
回复 19# 聆雨淋夜


    因为(.*)(.*\n){2}前面的(.*)贪婪匹配了56,后面的第一次只匹配了\n,第二次才匹配到df8 2\n
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP