используя awk для проверки между двумя датами - PullRequest
2 голосов
/ 12 ноября 2010

У меня есть файл с несколькими структурами данных, например:

eventTimestamp: 2010-03-23T07:56:19.166
result: Allowed
protocol: SMS
payload: RCOMM_SMS

eventTimestamp: 2010-03-23T07:56:19.167
result: Allowed
protocol: SMS
payload: RCOMM_SMS

eventTimestamp: 2010-03-23T07:56:19.186
result: Allowed
protocol: SMS
payload: SMS-MO-FSM

eventTimestamp: 2010-03-23T07:56:19.197
result: Allowed
protocol: SMS
payload: COPS

eventTimestamp: 2010-03-23T07:56:29.519
result: Blocked
protocol: SMS
payload: COPS
type: URL_IWF
result: Blocked

Я хочу найти все события, которые являются полезной нагрузкой: SMS-MO-FSM или полезной нагрузкой: SMS-MO-FSM-ИНФО, произошедшее между 2010-03-23 ​​12:56:47 и 2010-03-23 ​​13:56:47.Запрашивая этот файл до сих пор, я использовал awk следующим образом:

cat checkThis.txt |
awk 'BEGIN{FS="\n"; RS=""; OFS=";"; ORS="\n"}
     $1~/eventTimestamp: 2010-03-23T14\:16\:35/ && $4~/SMS-MO-FSM-INFO|SMS-MO-FSM$/ {$1=$1 ""; print $0}'

, что даст мне все события, которые произошли во втором из 14:16:35 в 2010-03-23.Однако я пытаюсь придумать, как я могу поместить диапазон дат в свой запрос.Я мог бы использовать следующее, чтобы поместить даты в эпоху, но как я могу использовать следующее в моем awk, чтобы проверить, находится ли дата между необходимыми временами:

python -c "import time; ENGINE_TIME_FORMAT='%Y-%m-%dT%H:%M:%S'; print int(time.mktime(time.strptime('2010-03-23T12:52:52', ENGINE_TIME_FORMAT)))"

Я знаю, что это можно сделать в Python, ноДля этого я написал парсер на Python и хочу использовать этот метод в качестве альтернативного средства проверки, поэтому я хочу использовать awk, если это вообще возможно.

Я взял это немного дальше и создал скрипт Python для преобразования времени:

#!/usr/local/bin/python
import time, sys
ENGINE_TIME_FORMAT='%Y-%m-%dT%H:%M:%S'
testTime = sys.argv[1]
try:
    print int(time.mktime(time.strptime(testTime, ENGINE_TIME_FORMAT)))
except:
    print "Time to convert %s" % testTime
    raise

Затем я попытался использовать getline, чтобы присвоить преобразование переменной для сравнения:

cat checkThis.txt| awk 'BEGIN {FS="\n"; RS=""; OFS=";"; ORS="\n"; "./firstDate '2010-03-23T12:56:47'" | getline start_time; close("firstDate"); "./firstDate '2010-03-23T13:56:47'" | getline end_time; close("firstDate");} ("./firstDate $1" | getline) > start_time {$1=$1 ""; print $0}'
Traceback (most recent call last):
  File "./firstDate", line 4, in <module>
testTime = sys.argv[1]
IndexError: list index out of range

Getline работает в BEGIN, и я проверил его в окончательном виде, но якажется, есть проблемы в части сравнения сценария.

Ответы [ 2 ]

6 голосов
/ 13 ноября 2010

Ключевое наблюдение заключается в том, что вы можете сравнивать свои временные метки с помощью буквенно-цифровых сравнений и получать правильный ответ - в этом прелесть ISO 8601 нотации.

Таким образом, слегка адаптируя код - и форматируя, чтобы избежать прокрутки:

awk 'BEGIN {
        FS  = "\n"
        RS  = ""
        OFS = ";"
        ORS = "\n"
        t1  = "2010-03-23T07:45:00"
        t2  = "2010-03-23T08:00:00"
        m1  = "eventTimestamp: " t1
        m2  = "eventTimestamp: " t2
        }
$1 ~ /eventTimestamp:/ && $4 ~ /SMS-MO-FSM(-INFO)?$/ {
    if ($1 >= m1 && $1 <= m2) print $1, $2, $3, $4;
}' "$@"

Очевидно, вы могли бы поместить это в файл сценария - вам не хотелось бы часто его печатать. И точный и удобный ввод диапазона дат - одна из самых сложных частей. Обратите внимание, что я скорректировал временной диапазон в соответствии с данными.

При работе с образцами данных выводится одна запись:

eventTimestamp: 2010-03-23T07:56:19.186;result: Allowed;protocol: SMS;payload: SMS-MO-FSM
1 голос
/ 13 ноября 2010

Немного клуджа, но этот скрипт предполагает, что у вас есть команда unix "date". Также жестко запрограммировали ваши начальные и конечные метки времени в блоке BEGIN. Обратите внимание, что перечисленные выше данные вашего теста не попадают в интервалы времени начала / окончания образца.

#!/usr/bin/awk -f
BEGIN {
        command="date -f\"%s\" -d \"2010-03-23 12:56:47\""; command | getline startTime; close(command)
        command="date -f\"%s\" -d \"2010-03-23 13:56:47\""; command | getline endTime; close(command)
}

$0 ~ /^eventTimestamp:/ {
        command="date -f\"%s\" -d " $2; command | getline currTime; close(command)

        if (currTime >= startTime && currTime <= endTime) {
                printIt="true"
        }else{
                printIt="false";
        }
}

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