免费注册 查看新帖 |

Chinaunix

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

请教多行匹配问题  关闭 [复制链接]

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
11 [报告]
发表于 2004-12-06 16:32 |只看该作者

请教多行匹配问题

对html文件到处理,通常用perl来处理感觉会更好

论坛徽章:
0
12 [报告]
发表于 2004-12-07 05:36 |只看该作者

请教多行匹配问题

试试这个.

根据你提供的文件, 有以下假设:

1. 每行只有一个 <table> 或 </table>
2. <table> 可以嵌套.


  1. # cat ./a.html
  2. <html><head><title> Test </title></head><body>
  3. <p> Other line 1 </p>
  4. <table><tr><td>
  5. <table><tr><td>
  6. <p> table with 3 lines </p>
  7. </td></tr></table>
  8. </td></tr></table>
  9. <p> Other line 2 </p>
  10. <table><tr><td>
  11. <table><tr><td>
  12. <p> table with 7 lines </p>
  13. <p> table with 7 lines </p>
  14. <p> table with 7 lines </p>
  15. <p> table with 7 lines </p>
  16. <p> table with 7 lines </p>
  17. </td></tr></table>
  18. </td></tr></table>
  19. <p> Other line 3 </p>
  20. <table><tr><td>
  21. <table><tr><td>
  22. <p> table with lines 9 </p>
  23. <p> table with lines 9 </p>
  24. <p> table with lines 9 </p>
  25. <p> table with lines 9 </p>
  26. <p> table with lines 9 </p>
  27. <p> table with lines 9 </p>
  28. <p> table with lines 9 </p>
  29. </td></tr></table>
  30. </td></tr></table>
  31. <p> Other line 4 </p>
  32. </body></html>         

复制代码


  1. # cat ./1
  2. #!/bin/awk -f
  3. {
  4.   if (match($0,/<table>|<\/table>/)) {
  5.     if (substr($0,RSTART+1,1)=="t") {
  6.         i++
  7.         if (n==0 )
  8.                 n=NR
  9.     }
  10.     else
  11.         i--

  12.     m=NR - n - 1

  13.     if (i==0 && n != 0) {
  14.         if (m==3 || m==7) {
  15.           if (s=="")
  16.                 s=n","NR"d"
  17.           else
  18.                 s=s";"n","NR"d"
  19.         }
  20.         n=0
  21.     }
  22.    }
  23. }

  24. END {
  25.   if (i != 0) {
  26.         print "Format Error !!"
  27.         exit
  28.   }
  29.   if ( s != "" )
  30.         system("sed \""s"\" "ARGV[1])
  31.   else
  32.         print "No matches found !!"

  33. }                           

复制代码


运行:

# ./1 a.html
<html><head><title> Test </title></head><body>
<p> Other line 1 </p>
<p> Other line 2 </p>
<p> Other line 3 </p>
<table><tr><td>
<table><tr><td>
<p> table with lines 9 </p>
<p> table with lines 9 </p>
<p> table with lines 9 </p>
<p> table with lines 9 </p>
<p> table with lines 9 </p>
<p> table with lines 9 </p>
<p> table with lines 9 </p>
</td></tr></table>
</td></tr></table>
<p> Other line 4 </p>
</body></html>

论坛徽章:
0
13 [报告]
发表于 2004-12-07 12:50 |只看该作者

请教多行匹配问题

lightspeed      
你的代码给出注释如何?

论坛徽章:
0
14 [报告]
发表于 2004-12-08 16:47 |只看该作者

请教多行匹配问题

我等一下试一下,谢谢各位朋友的解答
如果成功了,我把代码贴出来share

论坛徽章:
0
15 [报告]
发表于 2004-12-09 00:41 |只看该作者

请教多行匹配问题

的确可用...太强了...!!

而且事实上...那个匹配比斑竹给的例子容易,因为中间行的内容都是有缩进的...因此在match那里,和计算行数那里都更简单一些...

斑竹你太强了...!!!

我尝试着看您的程序,但是依然有点困惑,您看看我理解错误的地方,烦劳您指正


  1. # cat ./1
  2. #!/bin/awk -f
  3. {
  4.   if (match($0,/<table>|<\/table>/)) {  #这里表示匹配<table>或</table>
  5.     if (substr($0,RSTART+1,1)=="t") { #这里的RSTART的初始值是??这一句似乎是判断某个字符为t..???
  6.         i++                      #开始计算行数
  7.         if (n==0 )
  8.                 n=NR   #如果一开始没有行号,则用这行作为行号
  9.     }
  10.     else
  11.         i--                       

  12.     m=NR - n - 1  #中间的行数

  13.     if (i==0 && n != 0) { #如果行数为0或标记号不为0
  14.         if (m==3 || m==7) {  #当行数为3或7时候...
  15.           if (s=="")  #这个s是??
  16.                 s=n","NR"d"  #给s赋予初值,没看明白
  17.           else
  18.                 s=s";"n","NR"d"  #这句...也没看明白,剩下的n=0这些也不懂思路了....
  19.         }
  20.         n=0
  21.     }
  22.    }
  23. }

  24. END {
  25.   if (i != 0) {
  26.         print "Format Error !!"
  27.         exit
  28.   }
  29.   if ( s != "" )
  30.         system("sed \""s"\" "ARGV[1])
  31.   else
  32.         print "No matches found !!"

  33. }
复制代码

论坛徽章:
0
16 [报告]
发表于 2004-12-09 01:36 |只看该作者

请教多行匹配问题



  1. # cat ./1
  2. #!/bin/awk -f
  3. {
  4.   if (match($0,/<table>|<\/table>/)) {  #这里表示匹配<table>或</table>
  5.     if (substr($0,RSTART+1,1)=="t") {

  6. # 当上句 match 匹配成功会自动设置变量 RSTART, 含义为匹配字符串第一个字符在整行中的位置.
  7. # 因此, substr($0,RSTART+1,1) 是取匹配字符串 <table>  或 </table>
  8. # 的第二个字符. 如果是 t, 当然说明匹配的是 <table> 了

  9.         i++                      # 由于匹配了 <table> , 表嵌套深度加 1
  10.         if (n==0 )
  11.                 n=NR   # 纪录一个表结构最外层开始的行号
  12.     }
  13.     else
  14.         i--     #      匹配了 </table> , 表嵌套深度减 1            

  15.     m=NR - n - 1  #中间的行数, 这句实际应放在下面 if(m=... 语句之前

  16.     if (i==0 && n != 0) { # 嵌套深度为0,但table开始的行号不为0, 说明刚刚完成一个表结构的扫描.
  17. # 当然,  如果 i==0 && n==0 则说明没有遇到表结构

  18.         if (m==3 || m==7) {  #当表包含行数为3或7时候, 符合删除条件

  19. # s 是传给 END 中 sed 的删除语句, 如 s="2,6d;8,16d"

  20.           if (s=="")  #    遇到第一个表时赋值,如 s="2,6d"
  21.                 s=n","NR"d"  
  22.           else
  23.                 s=s";"n","NR"d"  # 后面的表,需加";" ,  如 s=s";8,16d"
  24.         }
  25.         n=0  # 处理完一个表结构后, 表开始行数复零
  26.     }
  27.    }
  28. }

  29. END {
  30.   if (i != 0) { # 文件中的 <table> 和 </table> 总数不等,因此语法错误.
  31.         print "Format Error !!"
  32.         exit
  33.   }
  34.   if ( s != "" ) 
  35.         system("sed \""s"\" "ARGV[1]) # 调用 sed 删除相应的行
  36.   else
  37.         print "No matches found !!"

  38. }
复制代码


由于 html  是一种自由格式, 因此每一行可能有多个 <table> </table>
那样的话, 此程序就不灵了. 你可以自己写一个这种情况的,比较繁琐, 相信
你的 awk 水平一定会有个大的提高.

此外,  如果 <table> </table>  出现在 <!--  --> 中则失去 tag 含义.
总之, 要想符合各种条件, 几乎是不可能的.

论坛徽章:
0
17 [报告]
发表于 2004-12-09 01:51 |只看该作者

请教多行匹配问题

哇,还好我到freebsdchina去看了看帖子,没有早睡.否则就走宝了
谢谢您,我再看看

论坛徽章:
0
18 [报告]
发表于 2004-12-09 01:57 |只看该作者

请教多行匹配问题

啊,谢谢,这次看明白了...
以前我用sed的时候很少用到删除,即使用到也大多是替换删除某段...整行删除还是第一次学习

谢谢老大的注释,很详尽清晰,而且很佩服您最后连table不匹配情形都考虑到了...我写shell经常因为偷懒而不写容错或者错误反馈...惭愧ing

论坛徽章:
0
19 [报告]
发表于 2004-12-09 04:35 |只看该作者

请教多行匹配问题

偷qq那里天气的...我是在phpwind 2.02里面用

1.sh
  1. #!/bin/awk -f
  2. {
  3.   if (match($0,/^<\/table>/)) {  #这里表示匹配</table>
  4.         i++                       
  5.         if (i==2) {
  6.            s="1,"NR"d"
  7.         }
  8.   }
  9. }

  10. END {
  11.   if ( s != "" )
  12.         system("sed \""s"\" "ARGV[1])#调用 sed 删除相应的行
  13.   else
  14.         print "No matches found !!"

  15. }
复制代码


2.sh
  1. #!/bin/awk -f
  2. {
  3.   if (match($1,/^<link/)) {  #这里表示匹配<link
  4.            s=NR","NR+10"d"
  5.         }
  6. }

  7. END {
  8.   if ( s != "" )
  9.         system("sed \""s"\" "ARGV[1])#调用 sed 删除相应的行
  10.   else
  11.         print "No matches found !!"

  12. }
复制代码


然后最后一个weather.sh中调用他们

  1. #!/bin/sh
  2. wget -b http://appnews.qq.com/cgi-bin/news_weather_list
  3. sleep 20
  4. ./1.sh news_weather_list > weathertmp.htm
  5. ./2.sh weathertmp.htm > weather.htm
复制代码

论坛徽章:
0
20 [报告]
发表于 2004-12-09 18:39 |只看该作者

请教多行匹配问题

顶上去~~~~给更多的人看到斑竹的解答方法...我想不止我一个人遇到这个问题吧
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP