Извлеките содержание из файла между двумя шаблонами соответствия (Извлеките только HTML из файла),

У меня есть файл, который содержит другой вид текстовых форматов, моя цель состоит в том, чтобы извлечь только часть HTML и создать файл с этим HTML-кодом. Я думаю, что это возможно с grep или awk. Мой файл содержит также строки как это:

Sender name `<test@email.com>`

Я записал этот сценарий 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>
2
задан 31 October 2017 в 23:57

1 ответ

Мы можем достичь этой цели с помощью инструмента sed - потокового редактора для фильтрации и преобразования текста . Краткий ответ дан под пункт 5 ниже. Но я решил написать подробное объяснение.

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

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, перенаправив > вывод в новый file:

sed -n '/<html>/I,/<\/html>/I p' example.file -i.bak
sed -n '/<html>/I,/<\/html>/I p' example.file > new.file

Ссылки:

6
ответ дан 2 December 2019 в 01:42

Другие вопросы по тегам:

Похожие вопросы: