使用sed提取HTML数据

时间:2014-01-22 03:31:01

标签: linux sed awk

如果我有一行HTML

<td><em>data</em></td>

如何打印到stdout

<em>data</em>

如果该行的开头和结尾完全

<td>

</td>

完全标记。如果该行未以td标记开头或结尾,请勿打印该行。

我试过

sed 's/<td>\(*\)</td>/\1/'

但它并不完全奏效 提前谢谢。

4 个答案:

答案 0 :(得分:3)

这应该做:

echo "<td><em>data</em></td>" | awk '{gsub(/<\/?td>/,x)}8'
<em>data</em>

或者这个:

echo "<td><em>data</em></td>" | sed 's|</*td>||g'
<em>data</em>

或者:(更确切地说,因为?只代表一个字符)

echo "<td><em>data</em></td>" | sed 's|</\?td>||g'
<em>data</em>

要解决您的工作中出现的问题sed 's/<td>\(*\)</td>/\1/' 你几乎就在那里,但这个\(*\)不起作用,因为它现在不再重复*
添加一个简单的.使其有效,因为它代表任何字符。所以它应该是\(.*\)
在第二个td中,有一个正斜杠/。由于您使用/作为分隔符int必须为
像这样/\转发<\/td>,这样就可以了:

echo "<td><em>data</em></td>" | sed 's/<td>\(.*\)<\/td>/\1/g'
<em>data</em>

可以改为:

echo "<td><em>data</em></td>" | sed 's|<td>\(.*\)</td>|\1|g'
<em>data</em>

但正如您在上面的示例中所看到的,不需要使用反向引用。最好只是为了 删除你不需要的东西。


如果此if the beginning and end of the line have exactly表示行的开头/结尾没有其他内容 后参考:

sed 's|^<td>\(.*\)</td>$|\1|g'

只需删除:

sed 's:^<td>\|</td>$::g' 

awk

echo "<td><em>data</em></td>" | awk '{gsub(/^<td>|<\/td>$/,x)}8'
<em>data</em>

答案 1 :(得分:1)

$ sed -r 's:<td>(.*)<\/td>:\1:g' <<< '<td><em>data</em></td>'
<em>data</em>

如果您的要求与问题中提到的一样简单,那么sed可以使用。但是,如果要解析HTML标记,请考虑使用perl作为sed,这样可以提高效率。使用正确的工具完成工作。

答案 2 :(得分:1)

您接受awk吗?

cat INFILE.txt | awk '/<td>/ { found=1; next }; /<\/td>/ { found=0; next }; found {print}'
  • 其中 INFILE.txt 是输入文件
  • 即使代码跨越多行,此命令也会在<td></td>之间打印;)

答案 3 :(得分:1)

sed -n '\|^[[:blank:]]*<[tT][dD]>\(.*\)</[tT][dD]>[[:blank:]]*$| s//\1/p' YourFile

仅使用此td标记(包含任何空格)开始/关闭行打印内容 (-posix with GNU sed)