获取分隔符索引并转换 EPOCH 时间

获取分隔符索引并转换 EPOCH 时间

我需要在第一行中搜索时间并获取位置索引,然后将其他行的 EPOCH 时间转换为人类可读的时间。 EPOCH 时间位置是随机的,但它有一个标头。示例如下。

Name,city,time
ABC,New York,1667271686096
CDF,Palo Alto,1667271685202

答案1

假设输入是CSV,使用磨坊主( mlr) 将字段中的值time(无论它可能出现在字段的顺序中)从 Unix 时间转换为当前区域设置的本地时间表示形式:

$ mlr --csv put '$time = strftime_local($time,"%+")' file
Name,city,time
ABC,New York,Sat Sep 27 01:54:56 CEST 54803
CDF,Palo Alto,Sat Sep 27 01:40:02 CEST 54803
$ TZ=Canada/Central mlr --csv put '$time = strftime_local($time,"%+")' file
Name,city,time
ABC,New York,Fri Sep 26 18:54:56 CDT 54803
CDF,Palo Alto,Fri Sep 26 18:40:02 CDT 54803

对于 UTC 时间,使用strftime()代替strftime_local()

$ mlr --csv put '$time = strftime($time,"%+")' file
Name,city,time
ABC,New York,Fri Sep 26 23:54:56 UTC 54803
CDF,Palo Alto,Fri Sep 26 23:40:02 UTC 54803

对于其他时间格式,请为strftime()或函数提供更具体的时间格式字符串(请参阅系统上的strftime_local()手册):strftime

$ mlr --csv put '$time = strftime_local($time,"At the hour %H of day %j of the year %Y")' file
Name,city,time
ABC,New York,At the hour 01 of day 270 of the year 54803
CDF,Palo Alto,At the hour 01 of day 270 of the year 54803

根据您的 Miller 版本和系统,您可能希望始终使用更具体的时间格式字符串,或者您可能希望切换到更易于使用的sec2gmt()函数sec2localtime()

$ mlr --csv put '$time = sec2gmt($time)' file
Name,city,time
ABC,New York,54803-09-26T23:54:56Z
CDF,Palo Alto,54803-09-26T23:40:02Z
$ TZ=Europe/Stockholm mlr --csv put '$time = sec2localtime($time)' file
Name,city,time
ABC,New York,54803-09-27 01:54:56
CDF,Palo Alto,54803-09-27 01:40:02
$ TZ=Canada/Central mlr --csv put '$time = sec2localtime($time)' file
Name,city,time
ABC,New York,54803-09-26 18:54:56
CDF,Palo Alto,54803-09-26 18:40:02

答案2

对于 Perl,使用列表::更多实用工具first_index用于查找包含“时间”的第一个字段的索引号的函数模块,以及日期格式对于time2str()函数:

$ perl -MList::MoreUtils=first_index -MDate::Format -F, -lne '
  if ($.==1) {
    $tfield = first_index { m/time/i }, @F ;
  } else {
    $F[$tfield] = time2str("%Y-%m-%d %H:%M:%S",$F[$tfield])
  };
  print join(",",@F)' file.csv
Name,city,time
ABC,New York,54803-09-27 09:54:56
CDF,Palo Alto,54803-09-27 09:40:02

注意:perl的Date::Format模块对于时间戳大于的情况没有问题2038 年 1 月 19 日 03:14:07,而且一般 Perl 也不会,因为珀尔 v5.12(2010 年 4 月发布)。其他语言可能会或可能不会准确工作,具体取决于语言和/或操作系统是否仍在使用 32 位有符号整数作为时间值(Linux 在所有体系结构上切换到 64 位 time_t,甚至是 32 位架构,v5.1 版本)。 2020 年为 6 个)。

另请注意,所使用的两个模块均未作为 perl 的标准包含。你必须安装它们或者如果它们恰好是为你的发行版打包的,则通过你的发行版的包管理器(例如在 Debian 和衍生产品上sudo apt-get install libtimedate-perl liblist-moreutils-perl

相关内容