【问题标题】:How to use regex for multiple line pattern in shell script如何在 shell 脚本中将正则表达式用于多行模式
【发布时间】:2013-09-15 02:04:55
【问题描述】:

我想编写一个 bash 脚本,在 html 文件中找到一个模式,该模式跨越多行。

正则表达式文件:

<td class="content">
  some content
</td>
<td class="time">
  13.05.2013  17:51
</td>
<td class="author">
  A Name
</td>

现在我想用class="time" 找到&lt;td&gt;-tag 的内容。

所以原则上是以下正则表达式:

&lt;td class="time"&gt;(\d{2}\.\d{2}\.\d{4}\s+\d{2}:\d{2})&lt;/td&gt;

grep 似乎不是我可以使用的命令,因为...

  1. 它只返回完整的行或使用-o 的完整结果,而不仅仅是圆括号(...) 内的结果。
  2. 模式只在一行中查找

那么我怎么可能只得到一个带有13.05.2013 17:51 的字符串呢?

【问题讨论】:

标签: regex bash shell grep


【解决方案1】:

它不完全在那里,它出于某种原因打印了一个领先的换行符,但也许是这样的?

$ sed -n '/<td class="time">/,/<\/td>/{s/^<td class="time">$//;/^<\/td>$/d;p}' file 

13.05.2013  17:51

灵感来自https://stackoverflow.com/a/13023643/1076493

编辑:好吧,perl 总是有的!
欲了解更多信息,请参阅https://stackoverflow.com/a/1213996/1076493

$ perl -0777 -ne 'print "$1\n" while /<td class="time">\n  (.*?)\n<\/td>/gs' regex.txt 
13.05.2013  17:51

【讨论】:

    【解决方案2】:

    您的格式有多固定?如果您确定它看起来像那样,那么您可以使用sed 匹配第一行,获取下一行并打印它,如下所示:

    $  sed -n '/<td *class="time">/{n;p}' test
      13.05.2013  17:51
    

    您可以添加一些内容来涵盖它也位于同一行的情况。或者预处理文件以去除所有换行符,也可能折叠空格(显然不能用sed 完成)然后从那里开始。

    但是,如果它是来自其他地方的 HTML 文件,并且您无法确定格式,我会考虑使用其他具有解析 XML 库的脚本语言,否则任何解决方案都可能在格式变化。

    编辑添加了指向我最喜欢的 sed 资源的链接:http://www-rohan.sdsu.edu/doc/sed.html

    【讨论】:

      【解决方案3】:

      试试:

      awk '/^td class="time">/{gsub(ORS,x); print $2}' RS=\< FS=\> file
      

      awk '/^td class="time">/{print $2}' ORS= RS=\< FS='>[[:space:]]*' file
      

      【讨论】:

        猜你喜欢
        • 2016-06-25
        • 1970-01-01
        • 2010-12-10
        • 1970-01-01
        • 1970-01-01
        • 2013-08-17
        • 2012-01-25
        • 2019-03-27
        • 1970-01-01
        相关资源
        最近更新 更多