Вопрос или проблема
Я пытаюсь преобразовать формат данных с разделителями в вывод таблицы HTML для печати по электронной почте, и не уверен, как использовать разделитель «|» в формате HTML-таблицы.
Ниже приведен пример, который я мог бы использовать, если бы пробел был разделителем, но в этом примере я использую конвейер (|).
awk ' BEGIN {
print "Кому: '[email protected]'"
#print "MIME-Version: 1.0"
print "Тип содержания: text/html"
print "Тема: Это тестовое email-сообщение"
print "<html><body><table border=1 cellspacing=0 cellpadding=3>"
print "<tr>"
print "<td>SID</td>";
print "<td>PID</td>";
print "<td>Имя пользователя</td>";
print "<td>База данных</td>";
print "<td>Имя хоста</td>";
print "<td>Программа</td>";
print "<td>Подключено</td>";
print "<td>Время ожидания</td>";
print "<td>Время запроса</td>";
print "<td>EST стоимость</td>";
print "<td>SEQ SCAN</td>";
print "<td>Запрос</td>";
print "</tr>"
} {
print "<tr>"
print "<td>"$1"</td>";
print "<td>"$2"</td>";
print "<td>"$3"</td>";
print "<td>"$4"</td>";
print "<td>"$5"</td>";
print "<td>"$6"</td>";
print "<td>"$7"</td>";
print "<td>"$8"</td>";
print "<td>"$9"</td>";
print "<td>"$10"</td>";
print "<td>"$11"</td>";
print "<td>"$12"</td>";
print "</tr>"
} END {
print "</table></body></html>"
} ' /home/test/test.unl | sendmail -t
Внутри файла test.unl находятся данные ниже:
15422216|-1|dwhvo|test|pd244zax.test.corp|N/A| 10:56:53| -0:00:30|10:57:22|1045127|1|SELECT sba_sub_aux.sba_subscriber_id, sba_sub_aux.sba_id_number, sba_sub_aux.sba_matchcode, sba_sub_aux.sba_marketing, sba_su|
Я хотел бы добиться такого вывода в табличном формате через email.
awk -F '|'
работает для меня.
awk -F '|' ' BEGIN {
print "Кому: '[email protected]'"
#print "MIME-Version: 1.0"
print "Тип содержания: text/html"
print "Тема: Это тестовое email-сообщение"
print "<html><body><table border=1 cellspacing=0 cellpadding=3>"
print "<tr>"
print "<td>SID</td>";
print "<td>PID</td>";
print "<td>Имя пользователя</td>";
print "<td>База данных</td>";
print "<td>Имя хоста</td>";
print "<td>Программа</td>";
print "<td>Подключено</td>";
print "<td>Время ожидания</td>";
print "<td>Время запроса</td>";
print "<td>EST стоимость</td>";
print "<td>SEQ SCAN</td>";
print "<td>Запрос</td>";
print "</tr>"
} {
print "<tr>"
print "<td>"$1"</td>";
print "<td>"$2"</td>";
print "<td>"$3"</td>";
print "<td>"$4"</td>";
print "<td>"$5"</td>";
print "<td>"$6"</td>";
print "<td>"$7"</td>";
print "<td>"$8"</td>";
print "<td>"$9"</td>";
print "<td>"$10"</td>";
print "<td>"$11"</td>";
print "<td>"$12"</td>";
print "</tr>"
} END {
print "</table></body></html>"
} ' /home/test/test.unl | sendmail -t
Вывод отображается так, как я и хотел, в email.
Как прокомментировал @GillesQuénot, разделение полей на |
с помощью awk так же просто, как awk -F '|'
.
Сказав это, я бы рекомендовал определить несколько функций: одну для экранирования HTML-текста (ваши данные, похоже, не нуждаются в этом, но вы никогда не знаете), и другую для печати полного ряда таблицы; это сделает основной код “чище” и надежнее:
awk -F '|' '
BEGIN {
# ...
print "<html><body><table border=1 cellspacing=0 cellpadding=3>"
$0 = "SID|PID|Username|Database|Hostname|Program|Connected|Idle Time|Query Time|EST COST|SEQ SCAN|Query"
print_as_tr()
}
{
print_as_tr()
}
END {
print "</table></body></html>"
}
function print_as_tr( i) {
print "<tr>"
for (i = 1; i <= NF; i++)
print "<td>" html_text($i) "</td>"
print "</tr>"
}
function html_text(s) {
gsub(/&/, "&", s)
gsub(/</, "\\<", s)
gsub(/>/, "\\>", s)
return s
}
'
Если вы уберете завершающий |
и добавите заголовок:
SID|PID|Username|Database|Hostname|Program|Connected|Idle Time|Query Time|EST COST|SEQ SCAN|Query
Тогда это станет простым TSV с конвейером в качестве разделителя, и вы можете использовать, например, mlr
для преобразования в правильный CSV, который pandoc
может преобразовать в HTML:
{
echo 'SID|PID|Username|Database|Hostname|Program|Connected|Idle Time|Query Time|EST COST|SEQ SCAN|Query'
sed 's/|$//' ваш-файл
} |
mlr --itsvlite --ifs pipe --ocsv cat |
pandoc -s -f csv -t html -M 'pagetitle=Моя таблица' \
-V 'header-includes=<style>table,th,td{border:1px solid;border-collapse:collapse}</style>' > result.html
Это обеспечит правильное экранирование HTML в содержимом ячеек.
Чтобы выровнять некоторые столбцы по правому краю, как в вашем ожидаемом выводе, другой вариант – использовать markdown в качестве промежуточного формата.
{
echo 'SID|PID|Username|Database|Hostname|Program|Connected|Idle Time|Query Time|EST COST|SEQ SCAN|Query'
sed 's/|$//' ваш-файл
} |
mlr --itsvlite --ifs pipe --omd cat |
perl -pe 's{-+}{substr("110000101110",$n++,1)?"$&:":":$&"}ge if $. == 2' |
pandoc -s -f markdown -t html -M 'pagetitle=Моя таблица' -V 'header-includes=<style>table,th,td{border:1px solid;border-collapse:collapse}</style>' > result.html
Выше используется perl
для указания выравнивания каждого столбца на основе “битовой карты” 110000101110
(1 для правого, 0 для левого).
Осторожно: mlr
не экранирует синтаксические операторы markdown в ячейках таблицы. Поэтому, например, если у вас есть `foo`
или **bar**
в некоторых ячейках, они будут преобразованы pandoc
в соответствующий HTML (<code>foo</code>
, <strong>bar</strong>
).
Ответ или решение
Конвертация данных в формате, разделенном символом "|", в HTML-таблицу для отправки по электронной почте — задача, требующая внимания к деталям и понимания основных принципов работы с текстом и HTML. В этой статье мы рассмотрим, как можно выполнить эту задачу с помощью утилиты awk
, а также предложим дополнительные инструменты для улучшения вывода.
Шаг 1: Использование awk
для обработки данных
Для начала давайте разберемся с основным подходом с использованием команды awk
, которая является замечательным инструментом для обработки текстовых потоков. Мы будем использовать флаг -F
для определения символа разделителя.
Вот общая структура вашего кода с использованием awk
для преобразования данных в HTML-таблицу:
awk -F '|' '
BEGIN {
print "To: '<a href="https://example.com" class="__cf_email__" data-cfemail="xxxx">[email protected]</a>'"
print "Content-Type: text/html"
print "Subject: Это тестовое письмо"
print "<html><body><table border=1 cellspacing=0 cellpadding=3>"
print "<tr>"
print "<td>SID</td>"
print "<td>PID</td>"
print "<td>Username</td>"
print "<td>Database</td>"
print "<td>Hostname</td>"
print "<td>Program</td>"
print "<td>Connected</td>"
print "<td>Idle Time</td>"
print "<td>Query Time</td>"
print "<td>EST COST</td>"
print "<td>SEQ SCAN</td>"
print "<td>Query</td>"
print "</tr>"
}
{
print "<tr>"
for (i = 1; i <= NF; i++)
print "<td>" $i "</td>"
print "</tr>"
}
END {
print "</table></body></html>"
}' /path/to/your_file | sendmail -t
Шаг 2: Пояснение кода
1. Установка разделителя:
Мы задаем -F '|'
для разделения строк по символу "|" и обрабатываем каждую строку как записи, которые будут помещены в ячейки таблицы.
2. Заголовки таблицы:
В блоке BEGIN
мы определяем заголовки таблицы, чтобы создать первую строку HTML.
3. Заполнение данных:
Основная часть кода (внутри блока {}
) перебирает каждую строку входных данных, генерируя
4. Закрытие таблицы:
Блок END
завершает таблицу и HTML-документ.
Шаг 3: Улучшение вывода с функциями
Для упрощения и повышения надежности кода можно определить функции для обработки HTML-текста и печати строк таблицы, чтобы избежать дублирования кода.
Пример улучшенного кода:
awk -F '|' '
BEGIN {
print "Content-Type: text/html"
print "Subject: Это тестовое письмо"
print "<html><body><table border=1 cellspacing=0 cellpadding=3>"
print_table_row("SID|PID|Username|Database|Hostname|Program|Connected|Idle Time|Query Time|EST COST|SEQ SCAN|Query")
}
{
print_table_row($0)
}
END {
print "</table></body></html>"
}
function print_table_row(row_str, i) {
print "<tr>"
n = split(row_str, cells, "|")
for (i = 1; i <= n; i++)
print "<td>" cells[i] "</td>"
print "</tr>"
}
'
Альтернативные инструменты
Если вам требуется большая гибкость или более сложное форматирование, можно использовать инструменты, такие как mlr
(Miller) и pandoc
. Они позволяют конвертировать данные в более удобный для работы формат и обеспечивают корректное экранирование специальный символов.
Например:
{
echo 'SID|PID|Username|Database|Hostname|Program|Connected|Idle Time|Query Time|EST COST|SEQ SCAN|Query'
sed 's/|$//' your_file
} |
mlr --itsvlite --ifs pipe --ocsv cat |
pandoc -s -f csv -t html -M 'pagetitle=Моя таблица' \
-V 'header-includes=<style>table,th,td{border:1px solid;border-collapse:collapse}</style>' > result.html
Заключение
Конвертация данных, разделенных символом "|", в HTML-таблицу — это процесс, который можно легко автоматизировать с помощью awk
и других утилит. Это позволяет вам создавать структурированные отчеты и отправлять их по электронной почте. Убедитесь, что вы проверяете HTML на корректность отображения во всех почтовых клиентах, поскольку они могут по-разному интерпретировать HTML-код.