gpt4 book ai didi

linux - 从 shell 的 HTML 文档中按名称删除元素 - Sed 命令失败

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:39:02 25 4
gpt4 key购买 nike

我正在尝试从 Linux 服务器 (Red Hat 6.8) 上的 html 文件中删除嵌入式 CSS。例如文件1.htm如下:

abc
<style type="text/css">
whatever
1
2
3
</style>
def

而我需要的是

abc
def

我尝试了下面的 sed 命令

sed -i 's#<style type="text\/css">(.|\n)*<\/style>##g' 1.htm

但它不起作用。有人可以阐明这一点吗?谢谢~

最佳答案

为了匹配跨行,您必须指示sed一次读取整个文件

使用 GNU sed (Linux) v4.2.2+,最简单的方法是使用-z (其目的是读取 NUL 分隔的记录;在没有嵌入 NUL 的情况下,将读取整个文件)。

此外,鉴于您未转义使用 () 作为元字符,您必须通过 -r 激活对扩展 正则表达式的支持。选项,虽然你并不严格需要它,因为 (.|\n*) (相当于 .* )必须替换为 [^<]*为了可能匹配多个 <style>单个元素( .* ,因为 sed 正则表达式是贪婪,将匹配文件中最后 </style> 标记之前的所有内容,这将多个元素出现故障)。

sed -z -r -i 's#<style type="text/css">[^<]*</style>\n?##g' 1.htm

请注意,我附加了 \n?到正则表达式以确保替换后没有留下空行。
使用未转义的 ?还需要 -r .
由于您选择了 #作为 s分隔符,你不需要 \ -逃脱/字符。在正则表达式中。

使用 旧版 GNU sed版本,您可以使用循环 ( :a;$!{N;ba} ) 一次读取整个文件:

sed -r -i ':a;$!{N;ba}; s#<style type="text/css">[^<]*</style>\n?##g' 1.htm

通常,要获得更强大的解决方案,请使用 HTML/XML 感知工具,例如 xsltproc (见下文)。


通过 xsltproc 使用 XSLT 的可靠解决方案:

xsltprocma​​cOS一些 Linux 发行版(例如 Fedora)附带的第三方实用程序,并且可以轻松安装在其他发行版(例如,在 Ubuntu 上,使用 sudo apt-get install xsltproc )。

随着 --html选项,它能够应用 XSLT - 基于 HTML 文档的转换,而不仅仅是 XML 文档。

这是一个示例 bash基于 -based 的解决方案,演示了创建包含所有 <style> 的 HTML 文档的副本删除元素,感谢改编自this answer :

# Create a simple sample HTML document with 2 <style> elements at different
# levels of the DOM and save it as "file.html"
cat > file.html <<'EOF'
<html>
<head></head>
<body>
<style type="text/css">
* {
border: 1 solid black;
}
</style>
<p foo='bar'>
abc def
<style type="text/css">
* {
border: 2 dashed blue;
}
</style>
</p>
</body>
</html>
EOF

xsltproc然后可以应用 XSLT 模板 到 HTML 文件(通常,这样的模板也作为文件提供,但考虑到它的简洁性,我在内存中构建它并像文件一样通过bash process substitution ( <(...) ) ):

# Define the XSLT template that copies all nodes in the document except those
# named "style".
# For an explanation, see https://stackoverflow.com/a/322079/45375
template='<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>

<xsl:template match="style"/>

</xsl:stylesheet>'

# Invoke xsltproc with the template and the input file.
# --html tells xlstproc to process the file as HTML, both on input and on output.
xsltproc --html <(echo "$template") file.html

以上结果(注意 <style> 元素是如何被删除的):

<html>
<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></head>
<body>

<p foo="bar">
abc def

</p>
</body>
</html>

要用修改后的副本替换输入文件(模拟 sed -i ),使用类似:

xsltproc --html <(echo "$template") file.html > /tmp/file.$$ && mv /tmp/file.$$ file.html

关于linux - 从 shell 的 HTML 文档中按名称删除元素 - Sed 命令失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45024510/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com