寻找一种将星期几附加到行尾的方法

寻找一种将星期几附加到行尾的方法

在 Ubuntu 16.04 中,我试图找到一种方法,将星期几附加到文本文件中每行的末尾(给定字段 4 中的日期)。

样本数据:

Server ID,Make,"Server Room",Datestamp,Timestamp,Distance,Ping,Download,Upload,Payload,"Src IP Address",Hour,DOW
x6883101,HP,"Server Room A",2019-07-14,04:50:02,26.444,11.521,49193480,41904833,,192.168.1.1,4, 
s3398577,Dell,"Server Room B",2019-09-21,10:50:02,56.574,37.608,48955461,45858381,,192.168.1.1,10, 
x6883551,Dell,"Server Room A",2019-08-16,02:00:04,26.444,17.921,86551957,88775986,,192.168.1.1,2, 
s1555023,HP,"Server Room C",2018-02-06,04:50:01,516.574,402.527,907658,608152,,192.168.1.1,4, 
s3398023,HP,"Server Room B",2019-01-17,10:50:01,56.574,40.233,48484827,45620028,,192.168.1.1,10, 
s1555098,IBM,"Server Room C",2018-11-18,02:00:03,516.514,404.671,819027,601233,,192.168.1.1,2, 
x6883582,Dell,"Server Room A",2019-05-19,04:50:02,26.444,12.506,88871436,84360552,,192.168.1.1,4,

例如,对于数据线 #1 和 #2:

x6883101,HP,"Server Room A",2019-07-14,04:50:02,26.444,11.521,49193480,41904833,,192.168.1.1,4,Sunday
s3398577,Dell,"Server Room B",2019-09-21,10:50:02,56.574,37.608,48955461,45858381,,192.168.1.1,10,Saturday

我尝试过各种 SED 和 AWK,但没有任何结果。我尝试过 DATE 命令,但它似乎不喜欢输入。我已经能够将实际日期与

grep -w -o "20[0-9][0-9]-[0-9][0-9]-[0-9][0-9]*"

但我看到没有任何东西能够转换它并在行尾附加 DOW。

我错过了什么使得将星期几附加到每行数据的末尾?另外,我需要能够通过 CRONTAB 工作来完成此操作。

答案1

使用 GNU awk,你可以这样做:

gawk -i /usr/share/awk/inplace.awk -F, -v OFS=, -v date_field=4 '
  (t = mktime(gensub("-", " ", "g", $date_field) " 0 0 0")) > 0 {
    $NF = strftime("%A", t)};1' your-file
  • -i /usr/share/awk/inplace.awk:启用 gawk 的就地编辑模式,将输出写入一个新文件中,该新文件将替换输入文件。不使用-i inplaceas尝试首先从当前工作目录gawk加载inplace扩展(asinplace或),有人可能已经在其中植入了恶意软件。随系统提供的扩展inplace.awk的路径可能会有所不同,请参阅输出inplacegawkgawk 'BEGIN{print ENVIRON["AWKPATH"]}'
  • -F,-v OFS=,设置输入和输出字段分隔符
  • mktime()是一个 GNU awk 扩展,它解析格式中的字符串year month day hour minute second并返回相应的 Unix 纪元时间。这里,我们使用(另一个 gawk 扩展)将第四个字段( )中的gensub()替换为空格,从而将时间传递给。-YYYY-MM-DDYYYY MM DD 0 0 0mktime()
  • (t = mktime(...)) > 0 {...}1condition {action}在每个输入记录上运行的两对(此处线)。
    • 对于第一个,状况mktime()检查(分配给)返回的值是否t大于 0(如果无法解析日期规范则mktime()返回),在这种情况下-1行动正在运行。strftime()(另一个 gawk 扩展)就像它的 C 等效项一样用于格式化时间(这里存储的 unix 纪元时间t格式为%A:本地化的星期几名称)。我们将结果分配给第一个NF字段 ( $NF),NF它是包含当前记录中字段数量的特殊变量,也是$检索字段内容(或带有 的完整记录$ 0)的运算符。

    • 第二个 ( 1) 缺少行动{print}默认为(打印当前记录)的部分,以及状况( 1) 始终为真。这是无条件打印当前记录的惯用简短方法,如果您想更详细,您可以这样做:

          gawk -i /usr/share/awk/inplace.awk \
               -v FS=, \
               -v OFS=, \
               -v date_field=4 \
               -v current_record=0 \
               -v always=1 '
            {
              date_for_mktime = gensub("-", " ", "g", $date_field) " 0 0 0"
              unix_time = mktime(date_for_mktime)
            } 
            unix_time > 0 {
              $NF = strftime("%A", unix_time)
            }
            always {print $current_record}' your-file
      

如果您希望工作日名称始终为英文,无论用户的区域设置如何,您可以将区域设置修复为C( LC_ALL=C gawk...)。

答案2

磨坊主( mlr):

mlr --csvlite put '
  $Hour = ""; $DOW = strftime(strptime($Datestamp,"%Y-%m-%d"),"%A")
' file.csv

前任。

$ mlr --csvlite put '$Hour = ""; $DOW = strftime(strptime($Datestamp,"%Y-%m-%d"),"%A")' file.csv
Server ID,Make,"Server Room",Datestamp,Timestamp,Distance,Ping,Download,Upload,Payload,"Src IP Address",Hour,DOW
x6883101,HP,"Server Room A",2019-07-14,04:50:02,26.444,11.521,49193480,41904833,,192.168.1.1,,Sunday
s3398577,Dell,"Server Room B",2019-09-21,10:50:02,56.574,37.608,48955461,45858381,,192.168.1.1,,Saturday
x6883551,Dell,"Server Room A",2019-08-16,02:00:04,26.444,17.921,86551957,88775986,,192.168.1.1,,Friday
s1555023,HP,"Server Room C",2018-02-06,04:50:01,516.574,402.527,907658,608152,,192.168.1.1,,Tuesday
s3398023,HP,"Server Room B",2019-01-17,10:50:01,56.574,40.233,48484827,45620028,,192.168.1.1,,Thursday
s1555098,IBM,"Server Room C",2018-11-18,02:00:03,516.514,404.671,819027,601233,,192.168.1.1,,Sunday
x6883582,Dell,"Server Room A",2019-05-19,04:50:02,26.444,12.506,88871436,84360552,,192.168.1.1,,Sunday

该软件包miller可从 Ubuntu 16.04universe存储库获取。

答案3

我的第一反应和斯蒂芬一样。

Perl 也可以工作:

perl -MTime::Piece -F, -lape '
  if ($F[3] =~ /^[\d-]+$/) {
    $F[-1] = Time::Piece->strptime($F[3], "%Y-%m-%d")->strftime("%A");
    $_ = join ",", @F;
  }
' file

答案4

使用(以前称为 Perl_6)

~$ raku -ne 'BEGIN my %days  = ( 1 => "Monday", 2 => "Tuesday", 3 => "Wednesday", 4 => "Thursday", 5 => "Friday", 6 => "Saturday", 7 => "Sunday" ) andthen put get;  
             put $_, %days{.split(",")[3].Date.day-of-week.Str};'  file

或者:

~$ raku -ne 'BEGIN my %days  = ( 1 => "Monday", 2 => "Tuesday", 3 => "Wednesday", 4 => "Thursday", 5 => "Friday", 6 => "Saturday", 7 => "Sunday" );  
             $++ == 0 ?? .put !! put $_, %days{.split(",")[3].Date.day-of-week.Str};'  file

上面是用 Raku(Perl 系列编程语言)编码的答案。这两个示例都使用-ne自动打印逐行标志。

在第一个示例中,%days在块中声明了哈希值BEGIN。要打印标题行put get(对于两行标题,请使用put (get xx 2)。在第二个示例中,使用 Raku 的三元运算符来打印标题:$++ == 0?? (True) !!(False)。对于两行标题,请使用$++ < 2

这两个示例都打印出$_主题变量,后跟计算星期几的代码。此代码,.split(",")[3].Date.day-of-week.Str以逗号分割,采用零索引 == 3(第 4 列),将其作为Date对象读取,计算数字day-of-week,然后将其转换为Str字符串。然后在散列中查找该数字星期几%days{ … }以给出按字母顺序排列的日期。

输入示例:

Server ID,Make,"Server Room",Datestamp,Timestamp,Distance,Ping,Download,Upload,Payload,"Src IP Address",Hour,DOW
x6883101,HP,"Server Room A",2019-07-14,04:50:02,26.444,11.521,49193480,41904833,,192.168.1.1,4, 
s3398577,Dell,"Server Room B",2019-09-21,10:50:02,56.574,37.608,48955461,45858381,,192.168.1.1,10, 
x6883551,Dell,"Server Room A",2019-08-16,02:00:04,26.444,17.921,86551957,88775986,,192.168.1.1,2, 
s1555023,HP,"Server Room C",2018-02-06,04:50:01,516.574,402.527,907658,608152,,192.168.1.1,4, 
s3398023,HP,"Server Room B",2019-01-17,10:50:01,56.574,40.233,48484827,45620028,,192.168.1.1,10, 
s1555098,IBM,"Server Room C",2018-11-18,02:00:03,516.514,404.671,819027,601233,,192.168.1.1,2, 
x6883582,Dell,"Server Room A",2019-05-19,04:50:02,26.444,12.506,88871436,84360552,,192.168.1.1,4,

示例输出:

Server ID,Make,"Server Room",Datestamp,Timestamp,Distance,Ping,Download,Upload,Payload,"Src IP Address",Hour,DOW
x6883101,HP,"Server Room A",2019-07-14,04:50:02,26.444,11.521,49193480,41904833,,192.168.1.1,4, Sunday
s3398577,Dell,"Server Room B",2019-09-21,10:50:02,56.574,37.608,48955461,45858381,,192.168.1.1,10, Saturday
x6883551,Dell,"Server Room A",2019-08-16,02:00:04,26.444,17.921,86551957,88775986,,192.168.1.1,2, Friday
s1555023,HP,"Server Room C",2018-02-06,04:50:01,516.574,402.527,907658,608152,,192.168.1.1,4, Tuesday
s3398023,HP,"Server Room B",2019-01-17,10:50:01,56.574,40.233,48484827,45620028,,192.168.1.1,10, Thursday
s1555098,IBM,"Server Room C",2018-11-18,02:00:03,516.514,404.671,819027,601233,,192.168.1.1,2, Sunday
x6883582,Dell,"Server Room A",2019-05-19,04:50:02,26.444,12.506,88871436,84360552,,192.168.1.1,4,Sunday

https://raku.org

相关内容