Сценарий оболочки / регулярное выражение: извлечение через несколько строк - PullRequest
0 голосов
/ 30 октября 2008

Я пытаюсь написать скрипт разбора журнала для извлечения сбойных событий. Я могу вытащить их с помощью grep:

$ grep -A5 "FAILED" log.txt

2008-08-19 17:50:07 [7052] [14] DEBUG:      data: 3a 46 41 49 4c 45 44 20 20 65 72 72 3a 30 32 33   :FAILED  err:023
2008-08-19 17:50:07 [7052] [14] DEBUG:      data: 20 74 65 78 74 3a 20 00                            text: .
2008-08-19 17:50:07 [7052] [14] DEBUG:    Octet string dump ends.
2008-08-19 17:50:07 [7052] [14] DEBUG: SMPP PDU dump ends.
2008-08-19 17:50:07 [7052] [14] DEBUG: SMPP[test] handle_pdu, got DLR
2008-08-19 17:50:07 [7052] [14] DEBUG: DLR[internal]: Looking for DLR smsc=test, ts=1158667543, dst=447872123456, type=2
--
2008-08-19 17:50:07 [7052] [8] DEBUG:      data: 3a 46 41 49 4c 45 44 20 20 65 72 72 3a 30 32 34   :FAILED  err:024
2008-08-19 17:50:07 [7052] [8] DEBUG:      data: 20 74 65 78 74 3a 20 00                            text: .
2008-08-19 17:50:07 [7052] [8] DEBUG:    Octet string dump ends.
2008-08-19 17:50:07 [7052] [8] DEBUG: SMPP PDU dump ends.
2008-08-19 17:50:07 [7052] [8] DEBUG: SMPP[test] handle_pdu, got DLR
2008-08-19 17:50:07 [7052] [8] DEBUG: DLR[internal]: Looking for DLR smsc=test, ts=1040097716, dst=447872987654, type=2

Что меня интересует, так это для каждого блока код ошибки (т. Е. "023" часть ": FAILED err: 023" в первой строке) и номер dst (т. Е. "447872123456" из "dst" = 447872123456 "в последней строке.)

Может ли кто-нибудь помочь с однострочником оболочки, чтобы извлечь эти два значения, или дать несколько советов относительно того, как я должен подходить к этому?

Ответы [ 3 ]

2 голосов
/ 30 октября 2008
grep -A 5 FAILED log.txt | \              # Get FAILED and dst and other lines
    egrep '(FAILED|dst=)' | \             # Just the FAILED/dst lines
    egrep -o "err:[0-9]*|dst=[0-9]*" | \  # Just the err: and dst= phrases
    cut -d':' -f 2 | \                    # Strip "err:" from err: lines
    cut -d '=' -f 2 | \                   # Strip "dst=" from dst= lines
    xargs -n 2                            # Combine pairs of numbers

023 447872123456
024 447872987654

Как и для всех оболочек «один», почти наверняка есть более элегантный способ сделать это. Тем не менее, я нахожу итеративный подход очень успешным для получения того, что я хочу: начните с слишком большого количества информации (ваш grep), затем сузьте строки, которые я хочу (с помощью grep), затем вырежьте части каждой строки, которую я хочу ( вырезать).

Хотя использование набора инструментов linux занимает больше строк, вам нужно знать только основы нескольких команд, чтобы делать практически все, что вы хотите. Альтернативой является использование awk, python или других языков сценариев, которые требуют более специализированных знаний программирования, но занимают меньше места на экране.

0 голосов
/ 05 ноября 2008

Если всегда есть одинаковое количество полей, вы можете просто

grep -A5 "FAILED" log.txt | awk '$24~/err/ {print $24} $12~/dst/{print $12}' error.txt

err:023
dst=447872123456,
err:024
dst=447872987654,

И в зависимости от того, как выглядит остальная часть файла, вы можете пропустить grep all togther.

Часть " $ 24 ~ / err / {print $ 24} " сообщает awk напечатать поле № 24, если оно содержит err, ~ / XXX /, где XXX - регулярное выражение.

0 голосов
/ 30 октября 2008

Простое решение на Ruby, здесь filter.rb:

#! /usr/bin/env ruby
File.read(ARGV.first).scan(/:FAILED\s+err:(\d+).*?, dst=(\d+),/m).each do |err, dst|
  puts "#{err} #{dst}"
end

Запустите его с:

ruby filter.rb my_log_file.txt

И вы получите:

023 447872123456
024 447872987654
...