Awk извлекающий столбец, но только из одного ряда - PullRequest
2 голосов
/ 27 января 2020

У меня есть скрипт в следующей форме:

2017-12-11 10:20:16.993 ...

2017-12-12 10:19:16.993 ...

2017-12-13 10:17:16.993 ...

, и я хочу извлечь первый столбец с помощью awk - F., сравнить его с фактическим системным временем в секундах и распечатать строку, если разница меньше 300 секунд.

>   SYSTEM_TIME=$(date +%s)
>                 awk -F. -v system_time=$SYSTEM_TIME '{gsub(/[-:]/," ",$1); if(system_time-mktime($1) <= 300) {print $0}}' log.txt

Это мой код, но я не могу использовать mktime, потому что он не соответствует норме POSIX. Можно ли это сделать без этого?

Спасибо,

Ахмед

Ответы [ 2 ]

4 голосов
/ 27 января 2020

Общее примечание: файлы журналов часто являются неполными. Формат даты-времени указан, но часто часовой пояс отсутствует. Когда летнее время вступает в игру, оно может испортить всю вашу карму, если вы пропустили часовой пояс.


Примечание: Во всех приведенных ниже командах это будет Предполагается, что дата в файле журнала указана в UT C, а система работает в UT C. Если это не так, имейте в виду, что переход на летнее время создаст проблемы при выполнении любой из приведенных ниже команд в течение времени перехода на летнее время.


Комбинация date и awk: (не POSIX)

Если ваша команда date имеет флаг -d (не POSIX), вы можете выполнить следующее:

awk -v r="(date -d '300 seconds ago' '+%F %T.%3N)" '(r < $0)'

GNU awk only:

Если вы хотите использовать mktime, тогда будет проще просто:

awk 'BEGIN{s=systime();FS=OFS="."}
     {t=$1;gsub(/[-:]/," ",t); t=mktime(t)}
     (t-s < 300)' logfile

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

POSIX:

Если вы не можете использовать mktime но вы хотите использовать только posix, что также означает, что date не имеет флага -d, вы можете создать собственную реализацию mktime. Имейте в виду, что представленная здесь версия не вносит никаких изменений в часовой пояс, как это сделано с mktime. mktime_posix предполагает, что datestring в UT C

awk -v s="$(date +%s)" '
# Algorithm from "Astronomical Algorithms" By J.Meeus
function mktime_posix(datestring,    a,t) {
    split(datestring,a," ")
    if (a[1] < 1970) return -1
    if (a[2] <= 2) { a[1]--; a[2]+=12 }
    t=int(a[1]/100); t=2-t+int(t/4)
    t=int(365.25*a[1]) + int(30.6001*(a[2]+1)) + a[3] + t - 719593
    return t*86400 + a[4]*3600 + a[5]*60 + a[6]
}
BEGIN{FS=OFS="."}
{t=$1;gsub(/[-:]/," ",t); t=mktime_posix(t)}
(t-s <= 300)' logfile

Похожие: этот ответ , этот ответ

0 голосов
/ 27 января 2020

Я могу думать, делая это как короче.

#!/bin/bash

SYSTEM_TIME=$(date +%s)
LOGTIME=$( date "+%s" -d "$( awk -F'.'  '{print $1}' <( head -1 inputtime.txt ))" )
DIFFERENCEINSECONDS=$( echo "$SYSTEM_TIME $LOGTIME" | awk '{ print ($1 - $2)}' )

if [[ "$DIFFERENCEINSECONDS" -gt 300 ]]
then
    echo "TRIGGERED!"
fi

Надеюсь, это полезно для вас. Дайте мне знать.

Примечание. Я предположил, что ваш входной журнал может называться inputtime.txt . Вам, конечно, нужно изменить свое фактическое имя файла.

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