我有一个包含不同类型文本格式的文件,我的目标是仅提取 HTML 部分并使用此 HTML 代码创建文件。我认为使用grep
或是可能的awk
。我的文件还包含如下行:
Sender name `<[email protected]>`
我写了这个脚本cat file1.html | grep -E "<[^>]*>"
。但问题是它还会输出诸如Sender name
等行。我只想提取<html>
标签后的内容。所以这对我来说没用:
Return-Path: <[email protected]>
for <test@localhost> (single-drop); Thu, 21 Sep 2017 18:34:07 +0400 (+04)
Return-path: <[email protected]>
(envelope-from <[email protected]>)
References: <[email protected]>
From: test user <[email protected]>
X-Forwarded-Message-Id: <[email protected]>
Message-ID: <[email protected]>
In-Reply-To: <[email protected]>
答案1
我们可以通过工具实现这一目标sed
- 用于过滤和转换文本的流编辑器。简短的答案如下点 5下面。但我决定写一个详细的解释。
0。首先让我们创建一个简单的文件来测试我们的命令:
$ printf '\nTop text\nSender <[email protected]>\n\n<html>\n\tThe inner text 1\n</html>\n\nMiddle text\n\n<HTML>\n\tThe inner text 2\n</HTML>\n\nBottom text\n' | tee example.file
Top text
Sender <[email protected]>
<html>
The inner text 1
</html>
Middle text
<HTML>
The inner text 2
</HTML>
Bottom text
1.我们可以裁剪标签<html>
和之间的所有内容</html>
,包括它们,方法如下:
$ sed -n -e '/<html>/,/<\/html>/p' example.file
<html>
The inner text 1
</html>
选项
-e script
(--expression=script
) 向要执行的命令添加脚本。在本例中,添加的脚本是'/<html>/,/<\/html>/p'
。虽然我们只有一个脚本,但我们可以省略此选项。选项
-n
(--quiet
,--silent
)抑制模式空间的自动打印,并且与此选项一起我们还应该使用一些附加命令来告诉sed
要打印什么。此附加命令是打印命令
p
,添加到脚本末尾。如果sed
没有以选项启动-n
,该p
命令将复制输入。最后,通过两个逗号分隔的模式 -
/<html>/,/<\/html>/
- 我们可以指定一个范围。请注意,我们在这里使用转义作为分隔符的\
特殊字符。/
2.如果我们想裁剪标签<html>
和之间的所有内容</html>
而不打印它们,我们应该添加一些额外的命令:
$ sed -n '/<html>/,/<\/html>/{ /html>/d; p }' example.file
The inner text 1
花括号
{
和}
用于对命令进行分组。该命令
d
将删除与表达式相关的每一行html>
。
3.但是,我们的example.file
标签也有大写字母。所以我们应该让模式匹配不区分大小写。我们可以通过在正则表达式中<HTML>
添加标志来实现这一点:/I
$ sed -n '/<html>/I,/<\/html>/I{ /html>/Id; p }' example.file
The inner text 1
The inner text 2
- 正则表达式匹配的修饰符
I
是一个 GNU 扩展,它使得 REGEXP 以不区分大小写的方式进行匹配。
4.如果我们想要删除标签之间的所有 HTML 标签,我们可以添加一个附加命令,该命令将解析并“删除”以 开头和以 结尾的<html>
字符串:<
>
sed -n '/<html>/I,/<\/html>/I{ /html>/Id; s/<[^>]*>//g; p }' example.file
该命令将用空字符串-
s
替换与表达式匹配的字符串。/<[^>]*>/
//
s/<old>/<new>/
模式标志
g
将对正则表达式的所有匹配应用替换,而不仅仅是第一个。
在这种情况下,我们可能希望省略删除命令:
sed -n '/<html>/I,/<\/html>/I{ s/<[^>]*>//g; p }' example.file
5.为了在文件的位置进行更改并创建备份副本,我们可以使用选项-i
,或者我们可以通过sed
将>
输出重定向到新文件来基于输出创建新文件:
sed -n '/<html>/I,/<\/html>/I p' example.file -i.bak
sed -n '/<html>/I,/<\/html>/I p' example.file > new.file
参考: