Конвертировать регулярное выражение AWK в скрипт Python - PullRequest
0 голосов
/ 16 мая 2011

Доброе утро всем, Интересно, не могли бы вы помочь мне со следующим запросом: - Я только начал изучать Python на прошлых выходных после того, как мой коллега показал мне, как резко сократить время выполнения скрипта Bash, переписав его на Python. Я был поражен тем, как быстро он бежал. Теперь я хотел бы сделать то же самое с другим моим сценарием.

Этот другой скрипт читает файл журнала и, используя AWK, фильтрует определенные поля из журнала и записывает их в новый файл. Смотрите ниже регулярное выражение, которое выполняет скрипт. Я хотел бы переписать это регулярное выражение в Python, так как мой сценарий в настоящее время занимает около 1 часа для выполнения в файле журнала с около 100 000 строк. Я хотел бы сократить это время как можно больше.

cat logs/pdu_log_fe.log | awk -F\- '{print $1,$NF}' | awk -F\. '{print $1,$NF}' | awk '{print $1,$4,$5}' | sort | uniq | while read service command status; do echo "Service: $service, Command: $command, Status: $status, Occurrences: `grep $service logs/pdu_log_fe.log | grep $command | grep $status | wc -l | awk '{ print $1 }'`" >> logs/pdu_log_fe_clean.log; done

Эта команда AWK получает строки, которые выглядят так: -

2011-05-16 09:46:22,361 [Thread-4847133] PDU D <G_CC_SMS_SERVICE_51408_656.O_ CC_SMS_SERVICE_51408_656-ServerThread-VASPSessionThread-7ee35fb0-7e87-11e0-a2da-00238bce423b-TRX - 2011-05-16 09:46:22 - OUT - (submit_resp: (pdu: L: 53 ID: 80000004 Status: 0 SN: 25866) 98053090-7f90-11e0-a2da-00238bce423b (opt: ) ) >

И выводит такие строки: -

CC_SMS_SERVICE_51408 submit_resp: 0

Я сам пытался написать скрипт на Python, но застрял в написании регулярного выражения. Пока у меня есть следующее: -

#!/usr/bin/python

# Import RegEx module
import re as regex
# Log file to work on
filetoread = open('/tmp/ pdu_log.log', "r")
# File to write output to
filetowrite =  file('/tmp/ pdu_log_clean.log', "w")
# Perform filtering in the log file
linetoread = filetoread.readlines()
for line in linetoread:
    filter0 = regex.sub(r"<G_","",line)
    filter1 = regex.sub(r"\."," ",filter0)
# Write new log file
    filetowrite.write(filter1)
filetowrite.close()
# Read new log and get required fields from it
filtered_log =  open('/tmp/ pdu_log_clean.log', "r")
filtered_line = filtered_log.readlines()
for line in filtered_line:
    token = line.split(" ")
    print token[0], token[1], token[5], token[13], token[20]
print "Done"

Ужасно, я знаю, но, пожалуйста, имейте в виду, что я только начал изучать Python два дня назад.

Я искал в этой группе и в Интернете фрагменты кода, которые я мог бы использовать, но пока то, что я нашел, не соответствует моим потребностям или слишком сложно (по крайней мере, для меня).

Будем весьма благодарны за любые предложения и советы, которые вы можете дать мне по поводу выполнения этой задачи.

С другой стороны, можете ли вы порекомендовать хорошую книгу для изучения Python? Я прочитал книгу «A Byte of Python» от Swaroop C H (отличная вводная книга!) И сейчас читаю «Погружение в Python» Марка Пилигрима. Я ищу книгу, которая объясняет вещи в простых терминах и идет прямо к сути (аналогично тому, как был написан «Байт Python»)

Заранее спасибо

С уважением,

Младший

===== Ответ Илии, который прокомментировал ниже =====

Мои извинения, ребята, я пытался комментировать ответ Элая, но мой комментарий слишком длинный, и он не сохранится. Я также попытался ответить на свой пост, но, поскольку я новый пользователь, я не могу ответить до тех пор, пока через 8 часов !. так что мой единственный вариант - добавить редактирование к моему сообщению:)

В любом случае, в ответ на комментарий Элая: -

Хорошо, давайте посмотрим, моя цель - отфильтровать несколько полей из файла журнала и записать их в новый файл журнала. Текущий файл журнала, как я упоминал ранее, имеет тысячи строк, подобных этой: -

2011-05-16 09: 46: 22 361 [Thread-4847133] PDU D

Все строки в файле журнала похожи и имеют одинаковую длину (одинаковое количество полей). Большинство полей разделены пробелами, за исключением пары из них, которые я обрабатываю с помощью AWK (удаление "

Надеюсь, теперь все стало понятнее

С уважением,

Младший

1 Ответ

6 голосов
/ 16 мая 2011

Поскольку эти строки очень структурированы, для простоты (и скорости) я бы вообще не стал использовать регулярные выражения.Вот пример извлечения вашей первой части данных:

>>> line = "2011-05-16 09:46:22,361 [Thread-4847133] PDU D <G_CC_SMS_SERVICE_51408_656.O_ CC_SMS_SERVICE_51408_656-ServerThread-VASPSessionThread-7ee35fb0-7e87-11e0-a2da-00238bce423b-TRX - 2011-05-16 09:46:22 - OUT - (submit_resp: (pdu: L: 53 ID: 80000004 Status: 0 SN: 25866) 98053090-7f90-11e0-a2da-00238bce423b (opt: ) ) >"
>>> istart = line.find('<G_')
>>> iend = line.find('.', istart)
>>> line[istart+3:iend]
'CC_SMS_SERVICE_51408_656'

Другие поля могут быть извлечены аналогичным образом, в зависимости от точной структуры всех возможных линий.Трудно понять, что именно делает ваш AWK и как он применим к приведенному вами примеру.Было бы проще, если бы вы могли описать структуру ваших строк данных и что именно вам нужно извлечь.

Например, разделив строку на пробел (по умолчанию для split), вы получите:

>>> line.split()
['2011-05-16', '09:46:22,361', '[Thread-4847133]', 'PDU', 'D', '<G_CC_SMS_SERVICE_51408_656.O_', 'CC_SMS_SERVICE_51408_656-ServerThread-VASPSessionThread-7ee35fb0-7e87-11e0-a2da-00238bce423b-TRX', '-', '2011-05-16', '09:46:22', '-', 'OUT', '-', '(submit_resp:', '(pdu:', 'L:', '53', 'ID:', '80000004', 'Status:', '0', 'SN:', '25866)', '98053090-7f90-11e0-a2da-00238bce423b', '(opt:', ')', ')', '>']

Теперь вы можете свободно извлекать любые поля, которые вам нужны, до тех пор, пока (как вы говорите) формат очень фиксированный и всегда одни и те же поля.Итак:

>>> line.split()[13]
'(submit_resp:'

Немного подчищаем:

>>> line.split()[13].lstrip('(').rstrip(':')
'submit_resp'

Как видите, возможности безграничны.Я предлагаю вам ознакомиться с возможностями Python по обработке строк до того, как погрузитесь в регулярные выражения.Регулярные выражения полезны, но они не единственный инструмент для работы.Часто решения, основанные на альтернативных методах обработки строк, быстрее и проще для понимания.Конечно, вы всегда можете дополнить их регулярными выражениями.

PS Для книг / ресурсов по изучению Python - есть много SO вопросов по этому поводу.Запустите здесь и просмотрите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...