> ## Documentation Index
> Fetch the complete documentation index at: https://clickhouse.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Импорт и экспорт произвольных текстовых данных с помощью Template и регулярных выражений в ClickHouse

> Страница с описанием импорта и экспорта произвольных текстовых данных с помощью Template и регулярных выражений в ClickHouse

Часто приходится работать с данными в произвольных текстовых форматах. Это может быть нестандартный формат, некорректный JSON или повреждённый CSV. Стандартные парсеры, такие как CSV или JSON, подходят не для всех таких случаев. Но в ClickHouse для этого есть мощные форматы Template и Regex.

<div id="importing-based-on-a-template">
  ## Импорт по шаблону
</div>

Предположим, что мы хотим импортировать данные из следующего [файла журнала](https://clickhouse-docs-assets.s3.us-east-1.amazonaws.com/error.log):

```bash theme={null}
head error.log
```

```response theme={null}
2023/01/15 14:51:17 [error]  client: 7.2.8.1, server: example.com "GET /apple-touch-icon-120x120.png HTTP/1.1"
2023/01/16 06:02:09 [error]  client: 8.4.2.7, server: example.com "GET /apple-touch-icon-120x120.png HTTP/1.1"
2023/01/15 13:46:13 [error]  client: 6.9.3.7, server: example.com "GET /apple-touch-icon.png HTTP/1.1"
2023/01/16 05:34:55 [error]  client: 9.9.7.6, server: example.com "GET /h5/static/cert/icon_yanzhengma.png HTTP/1.1"
```

Мы можем использовать формат [Template](/docs/ru/reference/formats/Template/Template) для импорта этих данных. Нужно определить строку шаблона с плейсхолдерами значений для каждой строки входных данных:

```response theme={null}
<time> [error] client: <ip>, server: <host> "<request>"
```

Создадим таблицу, в которую импортируем данные:

```sql theme={null}
CREATE TABLE error_log
(
    `time` DateTime,
    `ip` String,
    `host` String,
    `request` String
)
ENGINE = MergeTree
ORDER BY (host, request, time)
```

Чтобы импортировать данные с помощью указанного шаблона, нужно сохранить строку шаблона в файл ([row.template](https://clickhouse-docs-assets.s3.us-east-1.amazonaws.com/row.template) в нашем случае):

```response theme={null}
${time:Escaped} [error]  client: ${ip:CSV}, server: ${host:CSV} ${request:JSON}
```

Мы задаём имя столбца и правило экранирования в формате `${name:escaping}`. Здесь доступно несколько вариантов, например CSV, JSON, Escaped или Quoted, для которых используются [соответствующие правила экранирования](/docs/ru/reference/formats/Template/Template).

Теперь мы можем использовать этот файл как аргумент параметра `format_template_row` при импорте данных (*обратите внимание: в конце файлов шаблона и данных **не должно быть** лишнего символа `\n`*):

```sql theme={null}
INSERT INTO error_log FROM INFILE 'error.log'
SETTINGS format_template_row = 'row.template'
FORMAT Template
```

И можем убедиться, что данные были загружены в таблицу:

```sql theme={null}
SELECT
    request,
    count(*)
FROM error_log
GROUP BY request
```

```response theme={null}
┌─request──────────────────────────────────────────┬─count()─┐
│ GET /img/close.png HTTP/1.1                      │     176 │
│ GET /h5/static/cert/icon_yanzhengma.png HTTP/1.1 │     172 │
│ GET /phone/images/icon_01.png HTTP/1.1           │     139 │
│ GET /apple-touch-icon-precomposed.png HTTP/1.1   │     161 │
│ GET /apple-touch-icon.png HTTP/1.1               │     162 │
│ GET /apple-touch-icon-120x120.png HTTP/1.1       │     190 │
└──────────────────────────────────────────────────┴─────────┘
```

<div id="skipping-whitespaces">
  ### Пропуск пробелов
</div>

Можно использовать [TemplateIgnoreSpaces](/docs/ru/reference/formats/Template/TemplateIgnoreSpaces), чтобы пропускать пробелы между разделителями в шаблоне:

```text theme={null}
Template:               -->  "p1: ${p1:CSV}, p2: ${p2:CSV}"
TemplateIgnoreSpaces    -->  "p1:${p1:CSV}, p2:${p2:CSV}"
```

<div id="exporting-data-using-templates">
  ## Экспорт данных с использованием Template
</div>

Мы также можем экспортировать данные в любой текстовый формат с помощью Template. В этом случае нужно создать два файла:

[Шаблон результирующего набора](https://clickhouse-docs-assets.s3.us-east-1.amazonaws.com/output.results), который задаёт структуру всего результирующего набора:

```response theme={null}
== Top 10 IPs ==
${data}
--- ${rows_read:XML} rows read in ${time:XML} ---
```

Здесь `rows_read` и `time` — системные метрики, доступные для каждого запроса. При этом `data` обозначает сгенерированные строки (`${data}` всегда должен идти первым плейсхолдером в этом файле), сформированные по шаблону, заданному в [**файле шаблона строки**](https://clickhouse-docs-assets.s3.us-east-1.amazonaws.com/output.rows):

```response theme={null}
${ip:Escaped} generated ${total:Escaped} requests
```

Теперь воспользуемся этими Template, чтобы экспортировать следующий запрос:

```sql theme={null}
SELECT
    ip,
    count() AS total
FROM error_log GROUP BY ip ORDER BY total DESC LIMIT 10
FORMAT Template SETTINGS format_template_resultset = 'output.results',
                         format_template_row = 'output.rows';

== Top 10 IPs ==

9.8.4.6 generated 3 requests
9.5.1.1 generated 3 requests
2.4.8.9 generated 3 requests
4.8.8.2 generated 3 requests
4.5.4.4 generated 3 requests
3.3.6.4 generated 2 requests
8.9.5.9 generated 2 requests
2.5.1.8 generated 2 requests
6.8.3.6 generated 2 requests
6.6.3.5 generated 2 requests

--- 1000 rows read in 0.001380604 ---
```

<div id="exporting-to-html-files">
  ### Экспорт в HTML-файлы
</div>

Результаты, сформированные по шаблону, также можно экспортировать в файлы с помощью конструкции [`INTO OUTFILE`](/docs/ru/reference/statements/select/into-outfile). Давайте сгенерируем HTML-файлы на основе заданных форматов [resultset](https://clickhouse-docs-assets.s3.us-east-1.amazonaws.com/html.results) и [row](https://clickhouse-docs-assets.s3.us-east-1.amazonaws.com/html.row):

```sql theme={null}
SELECT
    ip,
    count() AS total
FROM error_log GROUP BY ip ORDER BY total DESC LIMIT 10
INTO OUTFILE 'out.html'
FORMAT Template
SETTINGS format_template_resultset = 'html.results',
         format_template_row = 'html.row'
```

<div id="exporting-to-xml">
  ### Экспорт в XML
</div>

Формат Template можно использовать для создания любых текстовых файлов, включая XML. Просто задайте подходящий шаблон и выполните экспорт.

Также можно использовать формат [XML](/docs/ru/reference/formats/XML), чтобы получить стандартный XML-вывод, включая метаданные:

```sql theme={null}
SELECT *
FROM error_log
LIMIT 3
FORMAT XML
```

```xml theme={null}
<?xml version='1.0' encoding='UTF-8' ?>
<result>
        <meta>
                <columns>
                        <column>
                                <name>time</name>
                                <type>DateTime</type>
                        </column>
                        ...
                </columns>
        </meta>
        <data>
                <row>
                        <time>2023-01-15 13:00:01</time>
                        <ip>3.5.9.2</ip>
                        <host>example.com</host>
                        <request>GET /apple-touch-icon-120x120.png HTTP/1.1</request>
                </row>
                ...
        </data>
        <rows>3</rows>
        <rows_before_limit_at_least>1000</rows_before_limit_at_least>
        <statistics>
                <elapsed>0.000745001</elapsed>
                <rows_read>1000</rows_read>
                <bytes_read>88184</bytes_read>
        </statistics>
</result>

```

<div id="importing-data-based-on-regular-expressions">
  ## Импорт данных с помощью регулярных выражений
</div>

Формат [Regexp](/docs/ru/reference/formats/Regexp) подходит для более сложных случаев, когда входные данные нужно разбирать более нетривиальным способом. Разберём наш файл [error.log](https://clickhouse-docs-assets.s3.us-east-1.amazonaws.com/error.log), но на этот раз извлечём имя файла и протокол, чтобы сохранить их в отдельные столбцы. Сначала подготовим для этого новую таблицу:

```sql theme={null}
CREATE TABLE error_log
(
    `time` DateTime,
    `ip` String,
    `host` String,
    `file` String,
    `protocol` String
)
ENGINE = MergeTree
ORDER BY (host, file, time)
```

Теперь мы можем импортировать данные с помощью регулярного выражения:

```sql theme={null}
INSERT INTO error_log FROM INFILE 'error.log'
SETTINGS
  format_regexp = '(.+?) \\[error\\]  client: (.+), server: (.+?) "GET .+?([^/]+\\.[^ ]+) (.+?)"'
FORMAT Regexp
```

ClickHouse вставит данные из каждой группы захвата в соответствующий столбец в порядке следования. Проверим данные:

```sql theme={null}
SELECT * FROM error_log LIMIT 5
```

```response theme={null}
┌────────────────time─┬─ip──────┬─host────────┬─file─────────────────────────┬─protocol─┐
│ 2023-01-15 13:00:01 │ 3.5.9.2 │ example.com │ apple-touch-icon-120x120.png │ HTTP/1.1 │
│ 2023-01-15 13:01:40 │ 3.7.2.5 │ example.com │ apple-touch-icon-120x120.png │ HTTP/1.1 │
│ 2023-01-15 13:16:49 │ 9.2.9.2 │ example.com │ apple-touch-icon-120x120.png │ HTTP/1.1 │
│ 2023-01-15 13:21:38 │ 8.8.5.3 │ example.com │ apple-touch-icon-120x120.png │ HTTP/1.1 │
│ 2023-01-15 13:31:27 │ 9.5.8.4 │ example.com │ apple-touch-icon-120x120.png │ HTTP/1.1 │
└─────────────────────┴─────────┴─────────────┴──────────────────────────────┴──────────┘
```

По умолчанию ClickHouse выдаёт ошибку при наличии несовпавших строк. Если вы хотите вместо этого пропускать такие строки, включите параметр [format\_regexp\_skip\_unmatched](/docs/ru/reference/settings/formats#format_regexp_skip_unmatched):

```sql theme={null}
SET format_regexp_skip_unmatched = 1;
```

<div id="other-formats">
  ## Другие форматы
</div>

ClickHouse поддерживает множество форматов — как текстовых, так и двоичных — для самых разных сценариев и платформ. Подробнее о форматах и способах работы с ними читайте в следующих статьях:

* [Форматы CSV и TSV](/docs/ru/guides/clickhouse/data-formats/csv-tsv)
* [Parquet](/docs/ru/guides/clickhouse/data-formats/parquet)
* [Форматы JSON](/docs/ru/guides/clickhouse/data-formats/json/intro)
* **Regex и Template**
* [Native и двоичные форматы](/docs/ru/guides/clickhouse/data-formats/binary)
* [Форматы SQL](/docs/ru/guides/clickhouse/data-formats/sql)

Также обратите внимание на [clickhouse-local](https://clickhouse.com/blog/extracting-converting-querying-local-files-with-sql-clickhouse-local) — это портативный полнофункциональный инструмент для работы с локальными и удалёнными файлами без необходимости запускать сервер ClickHouse.
