我正在尝试使用缩小 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