Неверная дата при преобразовании метки времени с помощью awk

Обратите внимание, что umask — это не вычитание, а логическая операция И, основанная на umask.

Думайте о разрешениях в двоичном формате:

Таким образом, разрешение 0666 будет

110 110 110

Теперь umask 0541 будет

101 100 001

Для вычисления результатов мы отрицаем umask:

010 011 110

, а затем И то, что с разрешением.

Так

110 110 110  AND
010 011 110
=== === ===
010 010 110

И это отображается в -w--w -rw-

3
08.05.2020, 20:28
2 ответа

Способ, которым date может получить переменную TZ (и понять ее ), довольно сложен. Эта команда работает:

 $ date -d 'TZ="UTC" 08-May-2020 15:40:32' +"%s"
1588952432

А также ТЗ из базы данных Олсона:

$ date -d 'TZ="Europe/London" 08-May-2020 15:40:32' +"%s" 
1588948832

И обратите внимание, что времена эпохи различны 1588952432и 1588948832. Разница в один (1 )час из-за того, что в Лондоне -1и в UTC 0.

Имейте в виду, что формат довольно строгий, сначала TZ, все в одинарных кавычках, а значение TZ также в двойных кавычках. И, будучи таким строгим, еще и довольно ломким.

Таким образом, установка значений в массиве (в предположении bash, ksh или zsh):

entry=( 
        "[08-May-2020 15:40:32 UTC] PHP Warning:  Illegal string offset 'ID' in /home/example/public_html/wp-content/themes/example/functions.php on line 1290"
        "[08-May-2020 15:40:32] PHP Warning:  Illegal string offset 'ID' in /home/example/public_html/wp-content/themes/example/functions.php on line 1290"
        "[08-May-2020 15:40:32 Europe/London] PHP Warning:  Illegal string offset 'ID' in /home/example/public_html/wp-content/themes/example/functions.php on line 1290"
      )

Затем мы можем получить все значения из даты с помощью awk (обратите внимание на разные FS только для одного вызова awk (технически говоря :GNU awk или nawk )и использование разделения из-за различных количество элементов строки времени):

printf '%s\n' "${entry[@]}" | awk -F '[][]' '{
    n=split($2, val, / /, sep);
    cmd=sprintf("date +\"%%s\" -d '\''TZ=\"%s\" %s %s'\''",val[3],val[1],val[2]);
    cmd | getline var; close(cmd);
    print "["var"]"$3;
}'
[1588952432] PHP Warning:  Illegal string offset 'ID' in /home/example/public_html/wp-content/themes/example/functions.php on line 1290
[1588952432] PHP Warning:  Illegal string offset 'ID' in /home/example/public_html/wp-content/themes/example/functions.php on line 1290
[1588948832] PHP Warning:  Illegal string offset 'ID' in /home/example/public_html/wp-content/themes/example/functions.php on line 1290

Обратите внимание, что технически строка вида:

if ( (rc=(cmd | getline var)) != 1){ 
     print "error on calling the command date ",rc; exit 
};

Улавливает некоторые ошибки getline (в основном getline не может получить вывод команды ), но awk не может ни сообщить, ни воздействовать на номер ошибки из команды. Ответственность за прерывание выполнения лежит на команде, если это требуется. Единственное, что делает awk с ошибкой (или нет ), — это передает вывод stderr команды cmd непосредственно в stderr. Таким образом, вы увидите любой комментарий (или ошибку ), вызванную командой в stderr awk. Обязательно проверьте и обработайте их, если это необходимо. В противном случае выходной файл будет автоматически поврежден. Вы были предупреждены!. Что, кажется, то, о чем вы просите.

Нет, awk datetime()не может понять время TZ и, тем более, значения из базы данных Олсона.

3
28.04.2021, 23:15

@Isaac находится на правильном пути, и, пожалуйста, оставьте его ответ в качестве принятого, так как он, вероятно, подойдет для вашего ввода, но я бы сделал так, чтобы выявить случаи, когда ввод не начинается с ожидается строка [date+time], вызов dateзавершается с ошибкой или getlineв противном случае завершается неудачей, поэтому он завершается успешно, если в тексте сообщения есть ], который следует после метки времени, и поэтому он завершается со статусом выхода с ошибкой, если таковой имеется часть выполнения терпит неудачу:

$ cat tst.awk
match($0,/\[[^]]+] /) {
    dt  = substr($0,RSTART+1,20)
    tz  = substr($0,RSTART+22,RLENGTH-24)
    msg = substr($0,RSTART+RLENGTH)

    cmd = sprintf("date -d \047TZ=\"%s\" %s\047 +\047%%s\047", tz, dt)
    cmd | getline secs
    close(cmd)
}
secs == "" {
    printf "%s[%d]: failed to convert: \"%s\"\n", FILENAME, NR, $0 | "cat>&2"
    exit 1
}
{ print secs, msg; secs="" }

напр. учитывая этот входной файл (обратите внимание на последние 2 строки -первая имеет ]в части сообщения, а вторая имеет недопустимую дату):

$ cat file
[08-May-2020 15:40:32 UTC] PHP Warning:  Illegal string offset 'ID' in /home/example/public_html/wp-content/themes/example/functions.php on line 1290"
[08-May-2020 15:40:32] PHP Warning:  Illegal string offset 'ID' in /home/example/public_html/wp-content/themes/example/functions.php on line 1290
[08-May-2020 15:40:32 Europe/London] PHP Warning:  Illegal string offset 'ID' in /home/example/public_html/wp-content/themes/example/functions.php on line 290
[08-May-2020 15:40:32 Europe/London] PHP Warning:  array foo[] is bad, the sky is falling
[08-Bob-2020 15:40:32 Europe/London] PHP Warning:  Illegal string offset 'ID' in /home/example/public_html/wp-content/themes/example/functions.php on line 290

$ awk -f tst.awk file
1588952432 PHP Warning:  Illegal string offset 'ID' in /home/example/public_html/wp-content/themes/example/functions.php on line 1290"
1588952432 PHP Warning:  Illegal string offset 'ID' in /home/example/public_html/wp-content/themes/example/functions.php on line 1290
1588948832 PHP Warning:  Illegal string offset 'ID' in /home/example/public_html/wp-content/themes/example/functions.php on line 290
1588948832 PHP Warning:  array foo[] is bad, the sky is falling
date: invalid date ‘TZ="Europe/London" 08-Bob-2020 15:40:32’
file[5]: failed to convert: "[08-Bob-2020 15:40:32 Europe/London] PHP Warning:  Illegal string offset 'ID' in /home/example/public_html/wp-content/themes/example/functions.php on line 290"

$ echo "$?"
1

Эта последняя часть выхода со статусом сбоя имеет значение, поэтому вы можете написать сценарий, подобный awk 'script' file > tmp && mv tmp file, не беспокоясь о том, что вывод awk перезапишет ваш входной файл, даже если он не работает, или вы можете иначе проверить результатawk 'script' file

2
28.04.2021, 23:15

Теги

Похожие вопросы