Преобразование дат в 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 выполняет результирующую строку.
Что касается методологии или больших файлов или потоков, я просто возглавляю первые несколько строк и постепенно собираю одну строку. Выбрось код.