在 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 inplace
as尝试首先从当前工作目录gawk
加载inplace
扩展(asinplace
或),有人可能已经在其中植入了恶意软件。随系统提供的扩展inplace.awk
的路径可能会有所不同,请参阅输出inplace
gawk
gawk 'BEGIN{print ENVIRON["AWKPATH"]}'
-F,
并-v OFS=,
设置输入和输出字段分隔符mktime()
是一个 GNU awk 扩展,它解析格式中的字符串year month day hour minute second
并返回相应的 Unix 纪元时间。这里,我们使用(另一个 gawk 扩展)将第四个字段( )中的gensub()
替换为空格,从而将时间传递给。-
YYYY-MM-DD
YYYY MM DD 0 0 0
mktime()
(t = mktime(...)) > 0 {...}
和1
是condition {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