Как преобразовать столбец с миллисекундной меткой времени в файл, используя bash? - PullRequest
2 голосов
/ 26 мая 2020

Я пытаюсь преобразовать все значения из первого столбца файла с отметкой времени в миллисекундах в формат даты %Y-%m-%d %H:%M:%S. Но на выходе получается Di 26. Mai 15:04:00 CEST 2020000. Я использую эту команду:

cat throughput-vs-latency-40K-16.csv | sed 's/^/echo "/; s/\([0-9]\{10\}\)/`date -d @\1`/; s/$/"/' | bash

, и это файл

"Time","pre_aggregate[0]-IN","pre_aggregate[10]-IN",
1590491460000,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
1590491475000,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
1590491490000,0,0,0,0,0,0,0,0,
1590491505000,290.51666666666665,290.53333333333336,
1590491535000,1027.15,1027.15,1028.85,1028.8666666666666,
1590491550000,1394.1166666666666,1394.15,1394.15,1394.1333333333334,
1590491565000,1475.5333333333333,1473.3666666666666,

Я хотел бы получить вывод, приведенный ниже (пожалуйста, учитывайте только формат и отклоните правильное преобразование времени) :

"Time","pre_aggregate[0]-IN","pre_aggregate[10]-IN",
"2020-05-07 08:05:45",0,0,0,0,0,0,0,0,
"2020-05-07 08:06:45",290.51666666666665,290.53333333333336,
"2020-05-07 08:07:45",1027.15,1027.15,1028.85,1028.8666666666666,
"2020-05-07 08:05:45",1394.1166666666666,1394.15,1394.15,1394.1333333333334,
"2020-05-07 08:08:45",1475.5333333333333,1473.3666666666666,

Что мне не хватает в команде sed, чтобы дата была в этом формате 2020-05-07 08:09:45?

Ответы [ 3 ]

3 голосов
/ 26 мая 2020

Вы можете использовать это awk:

awk 'BEGIN {
   FS=OFS=","
}
NR > 1 {
   n = $1/1000
   cmd = "date -d @" n " +\"%Y-%m-%d %T\""
   $1 = "\"" ( (cmd | getline out) > 0 ? out : $1 ) "\""
   close(cmd)
} 1' file

"Time","pre_aggregate[0]-IN","pre_aggregate[10]-IN",
"2020-05-26 07:11:00",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
"2020-05-26 07:11:15",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
"2020-05-26 07:11:30",0,0,0,0,0,0,0,0,
"2020-05-26 07:11:45",290.51666666666665,290.53333333333336,
"2020-05-26 07:12:15",1027.15,1027.15,1028.85,1028.8666666666666,
"2020-05-26 07:12:30",1394.1166666666666,1394.15,1394.15,1394.1333333333334,
"2020-05-26 07:12:45",1475.5333333333333,1473.3666666666666,

n=$1/1000 сделано для преобразования миллисекундного c значения во второе значение перед вызовом date команда для преобразования в формат Y-m-d H:M:S.

2 голосов
/ 26 мая 2020

С помощью awk и strftime замените первое поле форматированным временем:

awk 'BEGIN{ FS=OFS=","; }  NR>1{ $1=strftime("\"%Y-%m-%d %H:%M:%S\"", $1/1000) } 1'

Что мне не хватает в команде sed, чтобы иметь дату в этом формате 2020-05- 07 08: 09: 45?

В sed это сделать невозможно. «Теоретически» возможно выполнить арифметику c в sed, но полученный скрипт для обработки очень больших значений, таких как 1590491490000, будет очень, очень, очень длинным. sed можно использовать для простого регулярного выражения замена , sed не может «вычислять» или «преобразовывать» значения. Используйте другие инструменты для таких заданий.

sed 's/^/echo "/; s/\([0-9]\{10\}\)/`date -d @\1`/;

sed не 'не понимает обратные кавычки `как подстановку команд, как это делает оболочка. Обратные кавычки берутся буквально в sed. Существует расширение GNU для выполнения содержимого замещающей строки, добавляя флаг e в конце команды s. Поскольку деление на 1000 равно удалению трех последних цифр, в GNU sed вы можете сделать:

sed '1!s/^\([0-9]*\)[0-9]\{3\},/date -d@\1 +\\""%Y-%m-%d %T\\"",/e'
#                                                                ^ execute the expression
#                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ get's executed
#                   ^^^^^^^^^^ effectively divides by 1000
#    ^^ execute for all except first line

Использование awk с strftime будет быстрее.

1 голос
/ 26 мая 2020

Не могли бы вы попробовать следовать в чистом виде awk.

awk '
BEGIN{
  FS=OFS=","
}
FNR==1{
  print
  next
}
{
  $1 = strftime("%D %T.000",substr($1,1,10))
  gsub("/","-",$1)
}
1
'  Input_file

2-е решение: Добавление еще одного решения, которое будет иметь " для запуска и конец столбца даты.

awk '
BEGIN{
  FS=OFS=","
}
FNR==1{
  print
  next
}
{
  $1 = strftime("\"%D %T.000\"",substr($1,1,10))
  gsub("/","-",$1)
}
1
' Input_file
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...