Sed替换模式

时间:2012-03-24 17:20:31

标签: bash shell sed

我的代码如下:

<td nowrap="nowrap" width="74">
<p align="center">server1</p>
</td>
<td nowrap="nowrap" width="74">
<p align="center">server2</p>
</td>

依此类推。我希望输出为:

<td nowrap="nowrap" width="74">server1</td>
<td nowrap="nowrap" width="74">server2</td>

我的方法应该是什么?例如,文件是server.html 我做过类似的事情:

sed "s/<p align="center">*</p>/*/" -i server.html

但它不起作用。

5 个答案:

答案 0 :(得分:2)

再次有人用正则表达式解析HTML ...好吧,以下命令似乎适用于您发布的特定示例:

sed -re 's/<p align="center">(.*?)<\/p>/\1/g'

但是,如果有任何微小的变化,它会破坏,请考虑使用HTML解析器。

编辑:没有正则表达式,可以使用相同的结果完成以下操作:

sed -e 's/<p align="center">//g' -e 's/<\/p>//g'

但它比第一个更脏。

答案 1 :(得分:2)

当您使用带有sed的正则表达式时,可以使用()

引用第X个匹配的\X

此外,在表达式中运行所有斜杠时,我会使用|作为sed分隔符,以使表达式稍微不透明。

sed -e "s|<p align=\"center\">\(.*\)</p>|\1|" server.html

答案 2 :(得分:2)

这是你的命令行......

sed "s/<p align="center">*</p>/*/" -i server.html

问题:

  1. 您在选项之前指定命令,而不是使用-e选项标识命令。 (不确定是否在AIX中考虑过。)
  2. 您没有将文本与有效的正则表达式匹配。
  3. close-paragraph有一个unescape斜杠,被视为分隔符。
  4. 您的替换字符串只是一个星号。
  5. 我不会为此使用sed。虽然你可能想出一个神秘的,不可读的脚本来处理这个使用GNU sed,它可能不会是可移植的,如果你是写的,你将无法在它写入后30分钟读取它并不熟悉sed和regex。

    你可以输出与你所要求的相同的东西:

    sed '/<p/s#<[^>]*>##g' server.html
    

    使用正则表达式处理HTML通常会遇到问题,但如果您只是处理有保证的可预测文本,那么AWK可能是一个合理的解决方案。

    #!/usr/bin/awk -f
    
    /^<td/ { line=$0; }
    /^<p/ { gsub(/<[^>]*>/,""); line=line $0; }
    /^<\/td/ { print line $0; }
    

    请注意,这不是可以编写的最优雅的awk脚本;事物的拼写比它们需要的更充分,这样你就可以看到它通常所做的模式匹配,所以你可以调整它以适应不同的HTML。

    替代方案:

    #!/usr/bin/awk -f
    
    BEGIN { ORS=""; }
    /^<p/ { gsub(/<[^>]*>/,""); }
    { print; }
    /^<\/td/ { printf("\n"); }
    

    您可以看到的另一件事是使用CSS更改<p><td>的行为。

答案 3 :(得分:0)

编写正则表达式来操作HTML并不是最好的方法。您应该查看HTML解析库并编写代码,以便在解析后转换HTML。

答案 4 :(得分:0)

这可能对您有用:

sed '/^<td nowrap="nowrap" width="74">$/{N;N;s/\n[^>]*>\([^<]*\)<\/p>\n/\1/}' file
<td nowrap="nowrap" width="74">server1</td>
<td nowrap="nowrap" width="74">server2</td>