如何获取标签中间的文字?

时间:2014-03-22 00:49:19

标签: bash sed

      <li><b> Some Text:</b></li><li><b> Some Text:</b></li>
      <pg>something else</pg> <li><b> Some Text:</b> </li>
      <li><b> Some Text:</b></li>
      <li><b> Some Text:</b> More Text </li> <li><b> Some Text:</b> More Text </li>

如果这是我的输入字符串和

      Some Text:
      Some Text:
      Some Text:
      Some Text: More Text 
      Some Text: More Text

这是我的输出但我得到的只是

      Some Text:
      Some Text:
      Some Text: More Text

这是我在linux中的shell脚本函数

     #!/bin/sh
     sed -n -e 's/.*<li>\(.*\)<\/li>.*/\1/p' $1 > temp
     sed -e 's/<[<\/b]*>//g' temp >out

请告诉我哪里出错了。

4 个答案:

答案 0 :(得分:2)

以下是GNU awk的一种方法(第一行是空白行):

$ gawk '
RT=="</b>"||RT=="</li>" && NF {
    gsub(/^ *| *$/,"")
    printf "%s%s",(ORS=!(NR%2)?"":"\n"),$0
}
END { print "\n" }' RS='</?b>|</?li>' file

Some Text:
Some Text:
Some Text:
Some Text:
Some Text:More Text
Some Text:More Text

答案 1 :(得分:1)

如果您不介意使用第三方工具 - 多平台网络抓取工具xidel - 它会变得如此简单为:

xidel file.html -e '/li'

这将提取所有(顶级)li元素的纯文本内容,并在单独的行上打印以生成所需的输出。

答案 2 :(得分:1)

首先要做的事情是:一般说话,使用一种理解HTML的工具(参见我的其他答案),而不是awksed进行HTML解析 - 作为@chepner简洁地使用如上所述:

  

不要用sed或awk解析HTML; sed用于基于行的编辑,awk用于基于字段的任务。两者都不适用于其元素可能跨越多行的一般结构化文本。

因此,下面的解决方案在有限的情况下工作,但不能很好地概括。


@jaypal已经提供了 GNU awk(gawk) - 具体答案。
这是一个应该使用所有awk种口味,它们接受正则表达式作为输入记录分隔符(RS(例如gawk,{{1 }}和mawk):

nawk

符合旧版和POSIX标准的awk -v RS='</?li>\n*' ' /^<b>/ { t=$0; gsub(/<\/?b>/, "", t); gsub(/^ +| +$/, "", t); print t} ' file 版本 - 例如 OSX 中基于BSD的版本 - 只接受单个文字字符。作为awk,所以上面不会工作;在OSX上,以下RS命令实现了相同的功能(也适用于Linux):

sed

两种解决方案都会修剪输出行的前导和尾随空格。

答案 3 :(得分:0)

#!/bin/sh

你的第一个sed行并不是你想要它做的: 每行只能匹配一次出现

sed -n -e 's/.*<li>\(.*\)<\/li>.*/\1/p' $1 > temp
this...........................^^

匹配....其余部分(显然不是你所期望的)

一个简单的解决方法是在进行任何其他处理之前将每个</li>更改为</li> plus linefeed

#!/bin/sh

sed -e 's/<\/li>/<\/li>\n/g' "$1" |\
sed -n -e 's/.*<li>\(.*\)<\/li>/\1/p' |\
sed -e 's/<[\/b]*>//g' >out

我不是专家......其他人可能会有一个更优雅的解决方案