sed匹配多行,但只有在看到某一行之后

时间:2011-09-30 09:01:43

标签: sed

我正在尝试用sed解析一些非常简单的rss。喜欢挑选封闭网址以收听最新消息。 例如:

sed -n -e 's/.*"\([^"]*\.mp3\)".*/\1/p' -e 's/.*<title>\([^<]*\)<.title>.*/\1/p'

虽然,我想要做的是仅在看到某个令牌后开始此匹配,在这种情况下为“&lt; item&gt;”,这样我就不会捕获任何Feed&lt; title&gt; s,或者这样。

GNU sed很好,我想我可以某种方式使用双地址格式'0,/ REGEXP /'但我不知道如何结合这个来实现上述

为Dawnofthedead添加:

foo
bar
baz
<title>fum</title>
baz
fie
<item>
  <title>1</title>
  <enclosure url="one.mp3">
</item>
<item>
  <title>2</title>
  <enclosure url="two.mp3">
</item>

应该给我

1
one.mp3
2
two.mp3

4 个答案:

答案 0 :(得分:2)

如果你坚持使用sed,请尝试这一行。这一行适用于给定的例子:

kent$  sed -nr '/<item>/,/<\/item>/p' yourFile|sed -nr '/<title>/{s#[ ]*<[/]?title>##g;p}; /<enclosure/{ s#.*url="(.*)">#\1#g;p}'

<强>测试

kent$  cat t
foo
bar
baz
<title>fum</title>
baz
fie
<item>
  <title>1</title>
  <enclosure url="one.mp3">
</item>
<item>
  <title>2</title>
  <enclosure url="two.mp3">
</item>

kent$  sed -nr '/<item>/,/<\/item>/p' t |sed -nr '/<title>/{s#[ ]*<[/]?title>##g;p}; /<enclosure/{ s#.*url="(.*)">#\1#g;p}'
1
one.mp3
2
two.mp3

答案 1 :(得分:1)

$ sed -n -f s.sed input
1
one.mp3
2
two.mp3

其中s.sed是:

/<item>/,/<\/item>/{
    s/^.*>\([^<]\+\).*$/\1/
    s/^.*"\(.*\)".*$/\1/
    />$/d
    p
}

答案 2 :(得分:0)

如果您需要在命令行中解析简单的XML(如RSS提要),为什么不尝试 xsltproc

它输入一个xml并可以应用xslt转换样式表。 你必须学习xslt语言,但你可以产生更好的输出。

答案 3 :(得分:0)

这可能对您有用:

sed '$!N;s/^\s*<title>\(.*\)<\/title>\n\s*<enclosure url="\([^"]*\)">/\1\n\2/p;D' file
1
one.mp3
2
two.mp3

而不是在<item>...</item>之间寻找两行<title>...<enclosure...