Конвертация дат в AWK - PullRequest
       63

Конвертация дат в AWK

17 голосов
/ 23 января 2010

У меня есть файл, содержащий много столбцов текста, включая отметку времени вдоль строк Fri Jan 02 18:23, и мне нужно преобразовать эту дату в формат MM/DD/YYYY HH:MM.

Я пытался использовать стандартный инструмент `date 'с awk getline для преобразования, но я не могу понять, как передать поля в команду' date 'в ожидаемом формате (цитируется с "или s,) поскольку getline нуждается в командной строке, заключенной в кавычки.

Что-то вроде "date -d '$1 $2 $3 $4' +'%D %H:%M'" | getline var

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

Ответы [ 3 ]

21 голосов
/ 23 января 2010

Если вы используете gawk, вам не нужен внешний date, который может быть дорогим для повторного вызова:

awk '
BEGIN{
   m=split("Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec",d,"|")
   for(o=1;o<=m;o++){
      months[d[o]]=sprintf("%02d",o)
    }
format = "%m/%d/%Y %H:%M"
}
{
split($4,time,":")
date = (strftime("%Y") " " months[$2] " " $3 " " time[1] " " time[2] " 0")
print strftime(format, mktime(date))
}'

Спасибо ghostdog74 за массив месяцев от за этот ответ .

17 голосов
/ 23 января 2010

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

awk '
{
    cmd ="date \"+%m/%d/%Y %H:%M\" -d \""$1" "$2" "$3" "$4"\""
    cmd | getline var
    print var
    close(cmd)
}' file

выход

$ ./shell.sh
01/02/2010 18:23

и если вы не используете инструменты GNU, как, например, в Solaris, используйте nawk

nawk 'BEGIN{
   m=split("Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec",d,"|")
   for(o=1;o<=m;o++){
      months[d[o]]=sprintf("%02d",o)
   }
   cmd="date +%Y"
   cmd|getline yr
   close(cmd)
}
{
    day=$3
    mth=months[$2]
    print mth"/"day"/"yr" "$4
} ' file
1 голос
/ 10 января 2019

У меня была похожая проблема при преобразовании даты из баз данных RRDTool с использованием rrdfetch, но я предпочел один лайнер, который я использовал с компьютерных дней Apollo.

Данные выглядели так:

localTemp             rs1Temp             rs2Temp      thermostatMode
1547123400: 5.2788174937e+00 4.7788174937e+00 -8.7777777778e+00 2.0000000000e+00
1547123460: 5.1687014581e+00 4.7777777778e+00 -8.7777777778e+00 2.0000000000e+00

Один вкладыш:

rrdtool fetch -s -14400 thermostatDaily.rrd MAX | sed s/://g | awk '{print "echo ""\`date -r" $1,"\`" " " $2 }' | sh

Результат:

Thu Jan 10 07:25:00 EST 2019 5.3373432378e+00
Thu Jan 10 07:26:00 EST 2019 5.2788174937e+00

На первый взгляд, это не выглядит очень эффективным для меня, но такая методология всегда оказывалась достаточно низкой в ​​большинстве случаев, даже для очень больших файлов на компьютере с очень низким энергопотреблением (например, 25 МГц машины NeXT). Да, МГц

Sed удаляет двоеточие, awk используется для печати других различных представляющих интерес команд, в том числе просто выводит переменные awk, а sh или bash выполняет результирующую строку.

Что касается методологии или больших файлов или потоков, я просто пишу первые несколько строк и постепенно собираю одну строку. Выбрось код.

...