sed to * not *编辑HTML标签

时间:2015-07-25 01:57:48

标签: html sed

关于如何使用sed来编辑/删除HTML标签,有无数的教程,他们都倾向于推荐一些非常接近的东西......

/usr/local/Cellar

我想要的是反过来。我想在内容上运行sed,并保留标签。我试图反转打开和关闭标签,但这不起作用。

例如,对于以下输入:

sed 's/<[^>]\+>//g'

我想在标签之外用“bar”替换“foo”,生成

<p><img src="foo.jpg">the foo</p>

<p><img src="foo.jpg">the bar</p> 标记只是一个例子。它不应该具体到那个。

1 个答案:

答案 0 :(得分:1)

你要问的是有很多错误的范围(例如内容在一行中分裂意味着有效匹配转义或无效匹配似乎有效),我会像@Cyrus建议那样做使用专用编辑器。也就是说,您可以尝试使用捕获组的sed解决方案:

sed 's/\(>[^<]*\)foo/\1bar/'

如果>之前没有标记打开,则匹配foo和匹配字foo之间的所有内容。替换是在foo(\1)之前匹配的所有内容,然后是替换单词bar,然后在foo(\2)之后匹配的所有内容。您需要多次运行才能在一行中获取所有匹配项。

但是,如果你真的喜欢冒险,那么这个sed脚本会处理一行上多个匹配的情况,并匹配线上的分割。它克服了我愚弄它的每一次尝试 - 警告经理!

#!/bin/bash
# replace.sh - wrap sed script for ease of controlling replacements

match="foo"
repl="bar"
infile="$1"

sed -E "
:line
s/(>[^<]*)$match/\1$repl/
//b line

/>[^<]*$/ {
    :linepump
    /^[^\n]*\n.*>/{P;D}
    N
    /(>[^<]*)$match/b line
    />[^<]*$/b linepump
} 
" $infile

要阻止部分字母数字匹配(foot => bart),请将

替换为sed脚本的第二行
s/(>([^<]*[^[:alnum:]<]|))$word([^[:alnum:]]|$)/\1$repl\3/

(其他选项包括[:alpha:][:space:])。

这是一个非文字的解释:

  1. 用下一行替换模式空间
  2. 应用替代操作
  3. 如果仍然匹配,请转到2。
  4. 如果该行未包含>或在<之后有>,请转到1.
  5. 如果\n后跟>,请打印并清除第一个换行符之前的所有内容,然后转到4。*
  6. 在模式空间中添加下一行,前面有\n
  7. 如果有匹配转到2。
  8. 转到4。
  9. * 这会将最新的开始标记混洗到模式空间的开头:减少缓冲区重新分配,缩小搜索空间。这会对性能造成巨大影响 - 我的机器加速50倍。