LinuxSir.Org  
| 网站首页 | 注册账号 | 论坛帮助 |

欢迎来到LinuxSir.Org!
您还未登录,请登录后查看论坛,或者点击论坛上方的注册链接注册新账号。


发表新主题 回复
精华主题  
主题工具
旧 04-04-09, 22:32 第 1 帖
yongjian
 
yongjian 的头像
 
 
★版☆主★  
  注册日期: May 2003
  我的住址: Linux
  帖子: 2,572
  精华: 9
 

标题: sed/awd的新问题...


还是关于使用sed和awk。有这样的一个文件,列出其中的三列如:
----------------------------------------------------------------------------

1~906071~213435245(Apr 08 time 2004)
### EVENT ###
aksldlamalsdf
asdjalskdfjal

### END EVENT ###
PROCESSED

1~906072~458748239(Apr 08 time 2004)
### EVENT ###
kdieiejr
jkjviej

### END EVENT ###
PARSING_FAILED

1~906073~8782293(Apr 08 time 2004)
### EVENT ###
ierueio
dkjfire

### END EVENT ###
PARSING_FAILED

----------------------------------------------------------------------------------------------
这个文件的头和尾有空行, “### EVENT ###” 和“### END EVENT ###” 之间有空行。问题还是如何利用sed或awk得到这样的结果:
1. 去掉头和尾的空行。
2. 去掉“### EVENT ###” 和“### END EVENT ###”之间的那个空行。
3. 保留EVENT之间的空行。
4. 只显示带有PARSING_FAILED的EVENT。 可不是就是PARSING_FAILED的那一行,是PARSING_FAILED那整个EVENT。如:
-------------------------------------------------------------------------------------
1~906073~8782293(Apr 08 time 2004)
### EVENT ###
ierueio
dkjfire
### END EVENT ###
PARSING_FAILED

1~906072~458748239(Apr 08 time 2004)
### EVENT ###
kdieiejr
jkjviej
### END EVENT ###
PARSING_FAILED
-------------------------------------------------------------------------------------

惭愧,在下的sed/awk都不精,还请shell高手指教。谢谢!!!!!!!!!!!!!
  yongjian 当前离线   回复时引用此帖
旧 04-04-09, 23:26 第 2 帖
r2007
 
r2007 的头像
 
 
注册会员  
  注册日期: Jul 2003
  帖子: 166
  精华: 0
 

有点复杂,请楼主先试试吧。
代码:
/^### EVENT ###/ { x G : a N /\n### END EVENT ###/ !b a N /\nPARSING_FAILED/ { s/\n\n/\n/g N p } } h
  r2007 当前离线   回复时引用此帖
旧 04-04-09, 23:28 第 3 帖
yongjian
 
yongjian 的头像
 
 
★版☆主★  
  注册日期: May 2003
  我的住址: Linux
  帖子: 2,572
  精华: 9
 

哇,先谢谢!!! 虽然看不懂,但先试试,等着交差呢...







__________________
15" C2D MBP.
有简单的,不用复杂的!看到复杂的,尽量简单化!
Unix/Linux Philosophy: Be small! Be concentrated! One program does one thing and do it perfectly!
∞ years - 宇宙中最后的物质 Proton heat death. 之后,宇宙将以纯能量的形式永远存在。。。一切皆空
  yongjian 当前离线   回复时引用此帖
旧 04-04-09, 23:44 第 4 帖
yongjian
 
yongjian 的头像
 
 
★版☆主★  
  注册日期: May 2003
  我的住址: Linux
  帖子: 2,572
  精华: 9
 

我copy了r2007兄你的code, 做成sedcmd文件, 然后’ sed -f sedcmd targetfile', 结果是这样的:
-----------------------------------------------------------------------------
1~909284~1~1081446187(Apr 08 11:43:07 2004)
1~909284~1~1081446187(Apr 08 11:43:07 2004)
### EVENT ###
werweqerq
werqerqerq
dfee
END

### END EVENT ###
PROCESSED

1~909285~1~1081446207(Apr 08 11:43:27 2004)
1~909285~1~1081446207(Apr 08 11:43:27 2004)
### EVENT ###
aswerqwef
fsdfwew
qfeq
END

### END EVENT ###
PROCESSED

1~909286~1~1081446214(Apr 08 11:43:34 2004)
1~909286~1~1081446214(Apr 08 11:43:34 2004)
### EVENT ###
wergd
fdcqae
ccasd
END
### END EVENT ###
PARSING_FAILED
------------------------------------------------------------------------------------------

PARSING_FAILED 的EVENT是都连上了,可是为什么还有其他的非PARSING_FAILED的EVENT出来呢? 时间都变成了两行了。如何才能屏蔽所以非PARSING_FAILED的EVENT, 只显示PARSING_FAILED的EVENT呢?
多谢多谢!
  yongjian 当前离线   回复时引用此帖
旧 04-04-09, 23:50 第 5 帖
r2007
 
r2007 的头像
 
 
注册会员  
  注册日期: Jul 2003
  帖子: 166
  精华: 0
 

sorry,忘了说明,要加-n参数。
代码:
sed -nf sedcmd targetfile
  r2007 当前离线   回复时引用此帖
旧 04-04-09, 23:58 第 6 帖
home_king
 
home_king 的头像
 
 
临时退役版主  
  注册日期: Mar 2003
  帖子: 2,759
  精华: 15
 

我也给出我的awk脚本,较长。不过总觉得用awk比sed直观,而且更容易扩展。
代码:
[root@home root]# cat myawk2 BEGIN{ FS="\n" } { for(i=1;i<=NF;i++){ if($i ~ /^[0-9]/){ valids[++cnt]=$i continue } if($i == "### END EVENT ###"){ eof=1 valids[++cnt]=$i continue } if(eof == 1){ if($i == "PARSING_FAILED"){ for(j=1;j<=cnt;j++){ print valids[j] } print $i print "" } for(j=1;j<=cnt;j++){ delete valids[j] } eof=0 cnt=0 continue } valids[++cnt]=$i } } [root@home root]# awk -f myawk2 tmpdata 1~906072~458748239(Apr 08 time 2004) ### EVENT ### kdieiejr jkjviej ### END EVENT ### PARSING_FAILED 1~906073~8782293(Apr 08 time 2004) ### EVENT ### ierueio dkjfire ### END EVENT ### PARSING_FAILED
有一个小bug,过滤后的文本的最后一个空行没有去掉,兄弟自己去掉吧。我这边宿舍快要断电了,呵呵。







__________________
IBOX, a LiveCD distribution based on Gentoo, is fit for newbie.

IBOX brings to you:
- knoppix-style harddisk installation tool, by which you can install Gentoo in 20 minutes.
- hardware auto-configuration. You can run into X desktop directly.
- all-round software set, including OpenOffice, azureus.
- LiveCD-create-tools. Step-by-step, custom a LiveCD yourself with ease.

Any questions and feedbacks is welcome to home_king at 163 dot com
  home_king 当前离线   回复时引用此帖
旧 04-04-10, 00:00 第 7 帖
yongjian
 
yongjian 的头像
 
 
★版☆主★  
  注册日期: May 2003
  我的住址: Linux
  帖子: 2,572
  精华: 9
 

成了!加了n参数就只显示需要的输出了。 牛! 佩服!一定要好好研究一下r2007兄你的code。
  yongjian 当前离线   回复时引用此帖
旧 04-04-10, 00:04 第 8 帖
yongjian
 
yongjian 的头像
 
 
★版☆主★  
  注册日期: May 2003
  我的住址: Linux
  帖子: 2,572
  精华: 9
 

引用:
我也给出我的awk脚本,较长。不过总觉得用awk比sed直观,而且更容易扩展。 源码: [root@home root]# cat myawk2 BEGIN{ FS="\n" } { for(i=1;i<=NF;i++){ if($i ~ /^[0-9]/){ valids[++cnt]=$i continue } if($i == "### END EVENT ###"){ eof=1 valids[++cnt]=$i continue } if(eof == 1){ if($i == "PARSING_FAILED"){ for(j=1;j<=cnt;j++){ print valids[j] } print $i print "" } for(j=1;j<=cnt;j++){ delete valids[j] } eof=0 cnt=0 continue } valids[++cnt]=$i } } [root@home root]# awk -f myawk2 tmpdata 1~906072~458748239(Apr 08 time 2004) ### EVENT ### kdieiejr jkjviej ### END EVENT ### PARSING_FAILED 1~906073~8782293(Apr 08 time 2004) ### EVENT ### ierueio dkjfire ### END EVENT ### PARSING_FAILED 有一个小bug,过滤后的文本的最后一个空行没有去掉,兄弟自己去掉吧。我这边宿舍快要断电了,呵呵。 __________________ 永远的GNU! CeleronII 533MHZ + MS-6309 + HY256M SDRAM + Riva TNT2 + 15G Segate + HIGHLY OPTIMIZED lfs (id:11398) 华南农业大学01电子信息工程系(home_king@163.com)
哇! 强啊!学习!!!
  yongjian 当前离线   回复时引用此帖
旧 04-04-10, 23:04 第 9 帖
home_king
 
home_king 的头像
 
 
临时退役版主  
  注册日期: Mar 2003
  帖子: 2,759
  精华: 15
 

引用:
最初由 r2007 发表
有点复杂,请楼主先试试吧。
代码:
/^### EVENT ###/ { x G : a N /\n### END EVENT ###/ !b a N /\nPARSING_FAILED/ { s/\n\n/\n/g N p } } h
r2007兄,你的脚本有bug。楼主的第一个要求就是"去掉头尾空行"。你的脚本没有做到这一点。
请看你的脚本的过滤结果(注意尾部空行没有去掉):
----------------------------------------------------------------
1~906072~458748239(Apr 08 time 2004)
### EVENT ###
kdieiejr
jkjviej
### END EVENT ###
PARSING_FAILED

1~906073~8782293(Apr 08 time 2004)
### EVENT ###
ierueio
dkjfire
### END EVENT ###
PARSING_FAILED

-------------------------------------------------------------------

我给出我的改进awk脚本,它满足了楼主的所有要求,并且有很好的强壮性以及扩展性(这就是awk相对于sed的好处,而且awk脚本的可读性更好)。
代码:
#--log's filter-- # # Written by home_king <home_king@163.com> # /^[0-9]/,/PARSING_FAILED/{ if($0 ~ /^[0-9]/){ if(cnt==2){ print "" print $0 next } cnt++ } if(cnt==2 && $0 !~ /^$/){ print $0 } }
过滤结果:
---------------------------------------------------------------------
1~906072~458748239(Apr 08 time 2004)
### EVENT ###
kdieiejr
jkjviej
### END EVENT ###
PARSING_FAILED

1~906073~8782293(Apr 08 time 2004)
### EVENT ###
ierueio
dkjfire
### END EVENT ###
PARSING_FAILED
-------------------------------------------------------------------

此帖于 04-04-10 23:07 被 home_king 编辑.
  home_king 当前离线   回复时引用此帖
旧 04-04-10, 23:26 第 10 帖
KornLee
 
 
 
★☆★☆★☆★  
  注册日期: Nov 2002
  我的住址: LinuxWorld
  帖子: 6,960
  精华: 61
 

如果格式固定,可以试试这样
代码:
/home/javalee grep -B6 PARSING_FAILED file|sed '/^ /d;s/^--/ /g' 1~906072~458748239(Apr 08 time 2004) ### EVENT ### kdieiejr jkjviej ### END EVENT ### PARSING_FAILED 1~906073~8782293(Apr 08 time 2004) ### EVENT ### ierueio dkjfire ### END EVENT ### PARSING_FAILED /home/javalee
  KornLee 当前离线   回复时引用此帖
旧 04-04-10, 23:40 第 11 帖
home_king
 
home_king 的头像
 
 
临时退役版主  
  注册日期: Mar 2003
  帖子: 2,759
  精华: 15
 

嗯,还是讲究一下强壮性好,呵呵~~~
其实,我的awk脚本还有一个关于强壮性(非PARSING_FAILED域的分布不均匀性)的小bug,大家去找一下这个bug。我这边快断电了,明天给答案,呵呵~~~

此帖于 04-04-10 23:43 被 home_king 编辑.
  home_king 当前离线   回复时引用此帖
旧 04-04-11, 14:37 第 12 帖
home_king
 
home_king 的头像
 
 
临时退役版主  
  注册日期: Mar 2003
  帖子: 2,759
  精华: 15
 

Gawk的实现
开估了~~~
给出gawk脚本的最终版本。
除了满足楼主所有要求之外,还有以下特色:
它能适应"域间分布不均匀"(一个域以PARSING_FAILED或者其他字符串结尾)的可能性,并且巧妙地去掉头尾空行(详见运行结果)。
代码:
[root@home root]# cat myawk6 #!/bin/gawk { if($0 ~ /^1.*\(.*\)$/) flag=1 if(flag==1 && $0 !~ /^$/){ line[++i]=$0 } if($0 == "### END EVENT ###"){ endflag=1 next } if(endflag==1){ if($0 == "PARSING_FAILED"){ cnt++ if(cnt>=2) print "" for(j=1;j<=i;j++){ print line[j] delete line[j] } } else{ for(j=1;j<=i;j++){ delete line[j] } } i=0 flag=0 endflag=0 } }
为了验证脚本的强壮性,不妨先给出楼主的变化文本:
---------------------------------------------------------------

1~906072~458748239(Apr 08 time 2004)
### EVENT ###
kdieiejr
jkjviej

### END EVENT ###
PARSING_FAILED

1~906071~213435245(Apr 08 time 2004)
### EVENT ###
aksldlamalsdf
asdjalskdfjal

### END EVENT ###
PROCESSED

1~906072~458748239(Apr 08 time 2004)
### EVENT ###
kdieiejr
jkjviej

### END EVENT ###
PARSING_FAILED

1~906073~8782293(Apr 08 time 2004)
### EVENT ###
ierueio
dkjfire

### END EVENT ###
PARSING_FAILED

1~906071~213435245(Apr 08 time 2004)
### EVENT ###
aksldlamalsdf
asdjalskdfjal

### END EVENT ###
PROCESSED

----------------------------------------------------------------
以上就是可能存在的"域间分布不均匀性"。
请看运行结果:
-------------------------------------------------------------------
[root@home root]# gawk -f myawk6 tmpdata
1~906072~458748239(Apr 08 time 2004)
### EVENT ###
kdieiejr
jkjviej
### END EVENT ###
PARSING_FAILED

1~906072~458748239(Apr 08 time 2004)
### EVENT ###
kdieiejr
jkjviej
### END EVENT ###
PARSING_FAILED

1~906073~8782293(Apr 08 time 2004)
### EVENT ###
ierueio
dkjfire
### END EVENT ###
PARSING_FAILED
-------------------------------------------------------------------

awk与C类似,具有很多高级语言的特性,这个脚本我利用了C常见的"标记"(flag)技术。

此帖于 04-04-12 10:48 被 home_king 编辑.
  home_king 当前离线   回复时引用此帖
旧 04-04-11, 20:54 第 13 帖
r2007
 
r2007 的头像
 
 
注册会员  
  注册日期: Jul 2003
  帖子: 166
  精华: 0
 

教主兄给出的样本数据似乎有点片面,试试这个样本。虽然没有看到真正的源数据,按照楼主的描述,该文件能确定的关键字应该只有### EVENT ###,### END EVENT ###和PARSING_FAILED这3个,至于其它的都可能是任意字符。
代码:
A~906072~458748239(Apr 08 time 2004) ### EVENT ### kdieiejr jkjviej ### END EVENT ### PARSING_FAILED 1~906071~213435245(Apr 08 time 2004) ### EVENT ### aksldlamalsdf asdjalskdfjal ### END EVENT ### PROCESSED
  r2007 当前离线   回复时引用此帖
旧 04-04-11, 21:07 第 14 帖
home_king
 
home_king 的头像
 
 
临时退役版主  
  注册日期: Mar 2003
  帖子: 2,759
  精华: 15
 

to r2007:
嗯,A~906072~458748239(Apr 08 time 2004)这类条目不可能是任意字符,它还是有一定格式的,比如说,(日期)这两个括号还是有的,因为这是日志文件嘛。我修正了一下上面的脚本,老兄请看一下。
  home_king 当前离线   回复时引用此帖
旧 04-04-11, 21:24 第 15 帖
r2007
 
r2007 的头像
 
 
注册会员  
  注册日期: Jul 2003
  帖子: 166
  精华: 0
 

哦,我不是楼主,没有发言权。既然教主兄那么在意楼主的要求,比如说最后一个空行,不知是对“(日期)这两个括号还是有的”这个判定和楼主沟通过了,还是自己分析的。在楼主没有明确之前,或许正确或许错误,这好象不符合教主的风格吧?
  r2007 当前离线   回复时引用此帖
发表新主题 回复


主题工具

发帖规则
您 [不可以] 发表新主题
您 [不可以] 回复主题
您 [不可以] 上传附件
您 [不可以] 编辑您的帖子

已 [启用] BB 代码
已 [启用] 表情符号
已 [启用] IMG 代码
已 [禁用] HTML 代码
[论坛跳转…]


所有时间均为[北京时间]。现在的时间是 12:28


Powered by vBulletin 版本 3.6.8
版权所有 ©2000 - 2010, Jelsoft Enterprises Ltd.
官方中文技术支持: vBulletin 中文
版权所有 ©2002 - 2009, LinuxSir.Org