Преобразование дат в AWK

У меня есть файл, содержащий много столбцов текста, включая метку времени по строкам 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-переменные в строку.

Ответы

Ответ 1

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

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

Ответ 2

Если вы используете 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 для массива months из этого ответа.

Ответ 3

У меня была похожая проблема при преобразовании даты из баз данных 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 Machines). Да, МГц

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

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