如何使用 sed 从 HTML 缩小中排除 pre 标记?

如何使用 sed 从 HTML 缩小中排除 pre 标记?

我正在尝试使用缩小 HTMLsed

我的问题:我不想缩小<pre>标签内的任何内容,但无法使其工作。

这是我正在使用的:

sed ':a;N;$!ba;s@>\s*<@><@g' $html_file > ${html_file//.html/.minhtml}

这会缩小所有内容,包括 pre 标签内的内容。

我看过使用^[pre]但无法使其工作......

我还查看了使用sed /skipme/! s/foo/bar/

sed ':a;N;$!ba; /<pre>\.*<\/pre>/! s@>\s*<@><@g' $html_file > ${html_file//.html/.minhtml}

(...是的,我坚持使用sed,而不是其他工具,谢谢。)

答案1

您知道正则表达式是 HTML 解析的错误工具,很容易创建边缘情况使脚本失败,但您坚持使用错误的工具?好吧。

让我们看看要涵盖的案例: 可以有

  • 没有任何预格式化文本的行(进一步称为pre),
  • 一行pre,
  • 有些pre在一行内,
  • pre一行内有多个,
  • 超过pre一条线,甚至
  • pre从前一行结束的行开始pre

所有这些情况都在此示例文件中:

<x>    </x>
<pre>_ _</pre>
_ <pre>_</pre> _<x>    </x>_
_ <pre>_</pre> _<x>    </x> _ <pre>_</pre> _
_ <pre>_<x>    </x>_
_</pre> _
_<x>    </x>_<x>    </x>_
_ <pre>_
_<x>    </x>_<x>    </x>_
_</pre> _ <pre>
_
<x>    </x>_
</pre>

为了避免缩小部分的多次实现,让我们在第一遍中进行分离pre和非线性:pre

sed -z -e 's/<pre>/\n&/g;s_</pre>_&\n_g'

(显然您正在使用 GNU sed,否则您:a;N;$!ba;将无法工作。但是对于 GNU sed,您可以删除该代码并使用选项。)现在此代码在每个之前和之后-z添加了一个换行符。将其设置为一秒钟可以让我们需要处理的情况少得多(并且换行符不会对外部造成任何伤害)。<pre></pre>sed<pre>

sed -e '\_<pre>.*</pre>_b' -e '/<pre>/,\_</pre>_!s/>\s*</></g'

第一部分对于单行pre内容的行跳转到脚本的末尾;第二部分对其余行进行缩小虚拟,除了!多行的 ( )之外pre

一起,

sed -z -e 's/<pre>/\n&/g;s_</pre>_&\n_g' file.html | sed -e '\_<pre>.*</pre>_b' -e '/<pre>/,\_</pre>_!s/>\s*</></g'

产生

<x></x>

<pre>_ _</pre>

_ 
<pre>_</pre>
 _<x></x>_
_ 
<pre>_</pre>
 _<x></x> _ 
<pre>_</pre>
 _
_ 
<pre>_<x>    </x>_
_</pre>
 _
_<x></x>_<x></x>_
_ 
<pre>_
_<x>    </x>_<x>    </x>_
_</pre>
 _ 
<pre>
_
<x>    </x>_
</pre>

以及 – 瞧 – 外部空间被移除pre,但内部未受影响。

答案2

sed ':a;$!{N;ba;};s/@/@a/g;s/\n/@n/g;s/<pre/\n&/g;s/<\/pre>/&\n/g' test.html \
  | sed -r '/(^<pre|<\/pre>$)/!{s/@n//g;s/>\s+</></g;}' \
  | sed ':a;$!{N;ba;};s/\n//g;s/@n/\n/g;s/@a/@/g' >min.html

sed 草稿本——一系列 sed 示例

相关内容