从两个匹配模式之间的文件中提取内容(仅从文件中提取 HTML)

Dav*_*viD 2 bash scripts grep awk

我有包含不同类型文本格式的文件,我的目标是仅提取 HTML 部分并使用此 HTML 代码创建一个文件。我认为使用grepor是可能的awk。我的文件还包含这样的行:

Sender name `<test@email.com>`
Run Code Online (Sandbox Code Playgroud)

我写了这个脚本cat file1.html | grep -E "<[^>]*>"。但问题是它也将行输出为Sender name等。我只想在<html>标签之后提取内容。所以这对我没有用:

Return-Path: <test@test.com>
    for <test@localhost> (single-drop); Thu, 21 Sep 2017 18:34:07 +0400 (+04)
Return-path: <test@test.com>
    (envelope-from <test@test.com>)
References: <test@test.com>
From: test user <test@test.com>
X-Forwarded-Message-Id: <test@test.com>
Message-ID: <test@test.com>
In-Reply-To: <test@test.com>
Run Code Online (Sandbox Code Playgroud)

pa4*_*080 11

我们可以通过用于过滤和转换文本的工具流编辑器来实现这一目标。下面第 5 点给出了简短的答案。但我决定写一个详细的解释。sed

0.首先让我们创建一个简单的文件来测试我们的命令:

$ printf '\nTop text\nSender <example@email.com>\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 <example@email.com>

<html>
        The inner text 1
</html>

Middle text

<HTML>
        The inner text 2
</HTML>

Bottom text
Run Code Online (Sandbox Code Playgroud)

1.我们可以通过这种方式裁剪标签<html>和之间的所有内容</html>,包括它们:

$ sed -n -e '/<html>/,/<\/html>/p' example.file

<html>
        The inner text 1
</html>
Run Code Online (Sandbox Code Playgroud)
  • 选项-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
Run Code Online (Sandbox Code Playgroud)
  • 大括号{}用于对命令进行分组。

  • 该命令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
Run Code Online (Sandbox Code Playgroud)
  • I正则表达式匹配的修饰符是一个 GNU 扩展,它导致 REGEXP 以不区分大小写的方式进行匹配。

4.如果我们想删除标签之间的所有 HTML 标签,<html>我们可以添加一个额外的命令,该命令将解析和“删除”以以下开头<和结尾的字符串>

sed -n '/<html>/I,/<\/html>/I{ /html>/Id; s/<[^>]*>//g; p }' example.file
Run Code Online (Sandbox Code Playgroud)
  • 该命令s/<[^>]*>/用空字符串//-替换与表达式匹配的字符串s/<old>/<new>/

  • 模式标志g将替换应用到正则表达式的所有匹配项,而不仅仅是第一个。

在这种情况下,我们可能希望省略 delete 命令:

sed -n '/<html>/I,/<\/html>/I{ s/<[^>]*>//g; p }' example.file
Run Code Online (Sandbox Code Playgroud)

5.要在文件的位置进行更改并创建备份副本,我们可以使用选项-i,或者我们可以sed通过将>输出重定向到新文件来根据 的输出创建新文件:

sed -n '/<html>/I,/<\/html>/I p' example.file -i.bak
Run Code Online (Sandbox Code Playgroud)
sed -n '/<html>/I,/<\/html>/I p' example.file > new.file
Run Code Online (Sandbox Code Playgroud)

参考: