更改grep命令的分隔符

时间:2012-02-07 18:30:35

标签: regex linux shell unix grep

我正在使用 grep 来检测<a href="xxxx"> something here </a>
当链接在输入中的两行上分割时,这不起作用。我想grep检查直到它检测到</a>,但现在它只是将输入输入grep,直到它检测到新行。

因此,如果输入类似于<a href="xxxx"> something here </a>,则它可以正常工作,但如果输入类似

<a href="xxxx">

something here /a>    

,然后它没有。 任何解决方案?

6 个答案:

答案 0 :(得分:3)

我使用的是awk而不是grep。这应该有效:

awk '/a href="xxxx">/,/\/a>/' filename

答案 1 :(得分:1)

我认为使用某些xslt工具会有更少的麻烦,但你可以使用sed,awk或grep pcregrep的扩展版本来实现它,它具有多行模式(-M)。

答案 2 :(得分:1)

我建议折叠输入,以便打开和关闭标签在同一行,然后根据模式检查线条。使用 sed (1)的惯用方法:

sed '/<[Aa][^A-Za-z]/{ :A
     /<\/[Aa]>/ bD
     N
     bA
     :D
     /\n/ s// /g
}
# now try your pattern
/<[Aa][^A-Za-z] href="xxx"[^>]*>[^<]*something here[^<]*<\/[Aa]>/ !d'

答案 3 :(得分:0)

这可能是一个重复的问题: Grep search strings with line breaks

您可以使用tr '\n' ' '命令进行尝试,如其中一个答案中所述,如果您只需查找文件而不是行号。

答案 4 :(得分:0)

perl -e '$_=join("", <>); m#<a.*?>.*?<.*?/a>#s; print "$&\n";'

所以这里的诀窍是将整个输入读入$ _。然后运行标准/.../正则表达式。我使用了替代语法m#...#,这样我就不需要在xml中使用反斜杠&#34; /&#34; s。最后&#34; s&#34; postfix通过制作&#34;来实现多行匹配。&#34;也匹配换行符(注意选项&#34; m&#34;它改变了^和$的含义)。 &#34; $&安培;&#34;是匹配的字符串。这是你正在寻找的结果。如果只需要内部文本,可以在该部分周围放置圆括号并打印$ 1.

我假设您将</a>而不是/a>视为xml结束分隔符。

请注意,.*?.*的非贪婪版本,因此对于<a>1</a><a>2</a>,它只匹配<a>1</a>

请注意,嵌套节点可能会导致问题,例如<a><a></a></a>。这与尝试匹配嵌套括号时的情况相同&#34;(&#34;,&#34;)&#34;或&#34; {&#34;,&#34;}&#34;。这是一个更有趣的问题。正则表达式通常是无状态的,因此它们本身并不支持保持无限的括号嵌套深度。编程解析器时,通常使用正则表达式进行低级别的字符串匹配,并使用其他东西进行更高级别的标记解析,例如bison。有许多语言的野牛语法,可能还有xml。 xslt甚至可能更好,但我不熟悉它。但是对于一个非常简单的用例,你也可以在perl中处理这样的嵌套块:

嵌套括号处理代码:(这可以很容易地适应处理嵌套的xml块)

$_ = "a{b{c}e}f";

my($level)=(1);
s/.*?({|})/$1/; # throw away everything before first match
while(/{|}/g) {
   if($& eq "{") {
      ++$level;
   } elsif($& eq "}") {
      --$level;
      if($level == 1) {
         print "Result: ".$`.$&."\n";
         $_=$'; # reset searchspace to after the match
         last;
      }
   }
}

Result: {b{c}e}

答案 5 :(得分:0)

考虑egrep -3 '(<a|</a>)'

“ - 3”在每个正则表达式匹配周围打印最多3条周围线(比赛前3行和比赛后3行)。如果效果更好,也可以使用-1或-2。