манипулирование строками, обработка данных, регулярные выражения - PullRequest
0 голосов
/ 10 июля 2019

У меня есть .txt файл из 3 миллионов строк. Файл содержит данные, которые выглядят так:

# RSYNC: 0 1 1 0 512 0
#$SOA 5m localhost. hostmaster.localhost. 1906022338 1h 10m 5d 1s
# random_number_ofspaces_before_this text $TTL 60s
#more random information
:127.0.1.2:https://www.spamhaus.org/query/domain/$
test
:127.0.1.2:https://www.spamhaus.org/query/domain/$
.0-0m5tk.com
.0-1-hub.com
.zzzy1129.cn
:127.0.1.4:https://www.spamhaus.org/query/domain/$
.0-il.ml
.005verf-desj.com
.01accesfunds.com

В приведенных выше данных есть код, связанный со всеми доменами, перечисленными ниже. Я хочу превратить вышеуказанные данные в формат, который можно загрузить в HiveQL / SQL. Таблица HiveQL должна выглядеть следующим образом:

+--------------------+--------------+-------------+-----------------------------------------------------+
|    domain_name     | period_count | parsed_code |                      raw_code                       |
+--------------------+--------------+-------------+-----------------------------------------------------+
| test               |            0 | 127.0.1.2   |  :127.0.1.2:https://www.spamhaus.org/query/domain/$ |
| .0-0m5tk.com       |            2 | 127.0.1.2   |  :127.0.1.2:https://www.spamhaus.org/query/domain/$ |
| .0-1-hub.com       |            2 | 127.0.1.2   |  :127.0.1.2:https://www.spamhaus.org/query/domain/$ |
| .zzzy1129.cn       |            2 | 127.0.1.2   |  :127.0.1.2:https://www.spamhaus.org/query/domain/$ |
| .0-il.ml           |            2 | 127.0.1.4   |  :127.0.1.4:https://www.spamhaus.org/query/domain/$ |
| .005verf-desj.com  |            2 | 127.0.1.4   |  :127.0.1.4:https://www.spamhaus.org/query/domain/$ |
| .01accesfunds.com  |            2 | 127.0.1.4   |  :127.0.1.4:https://www.spamhaus.org/query/domain/$ |
+--------------------+--------------+-------------+-----------------------------------------------------+

Обратите внимание, что я не хочу вертикальных полос в любом выводе. Они просто для того, чтобы вышеперечисленное выглядело как таблица

Я предполагаю, что для создания таблицы HiveQL, подобной приведенной выше, потребуется преобразовать .txt в .csv или фрейм данных Pandas. Если создать .csv, то .csv, вероятно, будет выглядеть так:

domain_name,period_count,parsed_code,raw_code
test,0,127.0.1.2,:127.0.1.2:https://www.spamhaus.org/query/domain/$
.0-0m5tk.com,2,127.0.1.2,:127.0.1.2:https://www.spamhaus.org/query/domain/$
.0-1-hub.com,2,127.0.1.2,:127.0.1.2:https://www.spamhaus.org/query/domain/$
.zzzy1129.cn,2,127.0.1.2,:127.0.1.2:https://www.spamhaus.org/query/domain/$
.0-il.ml,2,127.0.1.4,:127.0.1.4:https://www.spamhaus.org/query/domain/$
.005verf-desj.com,2,127.0.1.4,:127.0.1.4:https://www.spamhaus.org/query/domain/$
.01accesfunds.com,2,127.0.1.4,:127.0.1.4:https://www.spamhaus.org/query/domain/$

Я бы заинтересовался решением на Python, но не был знаком с пакетами и функциями, необходимыми для выполнения описанных выше действий по обработке данных. Я ищу полное решение или код, чтобы построить свое собственное решение. Я предполагаю, что регулярные выражения понадобятся для определения строки «категория» или «код» в необработанных данных. Они всегда начинаются с ": 127.0.1." Я также хотел бы проанализировать код для создания столбца parsed_code и столбца period_count, который считает количество периодов в строке domain_name. Для тестирования создайте .txt образца данных, которые я предоставил в начале этого поста.

Ответы [ 2 ]

1 голос
/ 10 июля 2019

Независимо от того, как вы хотите отформатировать в конце, я полагаю, что первым шагом является разделение domain_name и code. Эта часть - чистый питон

rows = []
code = None
parsed_code = None
with open('input.txt', 'r') as f:
    for line in f:
        line = line.rstrip('\n')
        if line.startswith(':127'):
            code = line
            parsed_code = line.split(':')[1]
            continue
        if line.startswith('#'):
            continue
        period_count = line.count('.')                    
        rows.append((line,period_count,parsed_code, code))

Просто для иллюстрации, вы можете использовать pandas для удобного форматирования данных в виде таблиц, что может помочь, если вы хотите передать это в SQL, но это не является абсолютно необходимым. Последующая обработка строк также довольно проста в pandas.

import pandas as pd 
df = pd.DataFrame(rows, columns=['domain_name', 'period_count', 'parsed_code',  'raw_code'])
print (df)

печатает это:

         domain_name  period_count parsed_code                                           raw_code
0               test             0   127.0.1.2  :127.0.1.2:https://www.spamhaus.org/query/doma...
1       .0-0m5tk.com             2   127.0.1.2  :127.0.1.2:https://www.spamhaus.org/query/doma...
2       .0-1-hub.com             2   127.0.1.2  :127.0.1.2:https://www.spamhaus.org/query/doma...
3       .zzzy1129.cn             2   127.0.1.2  :127.0.1.2:https://www.spamhaus.org/query/doma...
4           .0-il.ml             2   127.0.1.4  :127.0.1.4:https://www.spamhaus.org/query/doma...
5  .005verf-desj.com             2   127.0.1.4  :127.0.1.4:https://www.spamhaus.org/query/doma...
6  .01accesfunds.com             2   127.0.1.4  :127.0.1.4:https://www.spamhaus.org/query/doma...
0 голосов
/ 10 июля 2019

Вы можете сделать все это с помощью стандартной библиотеки Python.

HEADER = "domain_name | code"    

# Open files
with open("input.txt") as f_in, open("output.txt", "w") as f_out:
    # Write header
    print(HEADER, file=f_out)
    print("-" * len(HEADER), file=f_out)

    # Parse file and output in correct format
    code = None
    for line in f_in:
        if line.startswith("#"):
            # Ignore comments
            continue
        if line.endswith("$"):
            # Store line as the current "code"
            code = line
        else:
            # Write these domain_name entries into the 
            # output file separated by ' | '
            print(line, code, sep=" | ", file=f_out)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...