我想获取由,
以下命令分隔的第 2 列的时间差。默认情况下,第一列工作正常。
桌子:
20220505,12:00:12,user,dept
20220505,12:00:25,user,dept
20220505,12:00:32,user,dept
命令:
awk -F: '{t=$1*3600+$2*60+$3} NR>1{printf( "%.6f\n", t-p)}{p=t}' inputfile
我尝试过:但未能得到正确的结果。
awk -F ',' $2 '{t=$1*3600+$2*60+$3} NR>1{printf( "%.6f\n", t-p)}{p=t}' inputfile
答案1
你需要告诉 awk 使用两个都 ,
并:
作为字段分隔符。请注意,这将更改字段的编号(因为两个字段分隔符都应用于每个输入行)。例如:
$ awk -F '[:,]' '{ t = $2*3600 + $3*60 + $4 }
NR > 1 { printf "%.6f\n", t-p }
{ p=t }' inputfile
13.000000
7.000000
请注意,这不会计算不同日期的时间差。为此,您需要将组合的日期和时间解析为一个time_t
值(即自纪元(1970 年 1 月 1 日午夜)以来的秒数)。例如,与GNUawk,使用以下mktime()
函数:
$ awk -F '[:,]' '{
# extract the year, month, and day from the first field
y = substr($1,1,4);
m = substr($1,5,2);
d = substr($1,7,2);
# create a space-separated datespec string, combining y,m,d with
# hours, minutes, and seconds from fields 2, 3, and 4
datespec = y " " m " " d " " $2 " " $3 " " $4;
# convert it to seconds since the epoch
t = mktime(datespec)
}
NR > 1 { printf "%.6f\n", t-p }
{ p=t }' inputfile
13.000000
7.000000
运行man awk
并搜索mktime
有关此函数如何工作的摘要。
答案2
使用乐(以前称为 Perl_6)
raku -e 'my @a = lines.map: *.split(","); my @b; for ^@a.elems -> $i { \
my $date = @a[$i][0].subst(/ ^ (\d**4)(\d**2)(\d**2) $/, {"$0-$1-$2"}); \
@b.push: "{$date}T@a[$i][1]Z".DateTime.Instant }; \
loop (my $i = 0; $i < @b.elems-1; $i++) { put @b[$i+1] - @b[$i] };'
Raku 使用以下方法处理日期和时间ISO 8601
互换标准, 内置。在第一个语句中,每个都以逗号lines
读入,并保存在数组中。数组已声明。然后循环行,第一列(日期)的元素创建连字符分隔,并且该字符串用于生成 ISO 8601之类的.这会立即转换为一个对象(以秒为单位)并添加到数组中。在最后的语句中,秒数被遍历并相互减去。split
","
@a
@b
subst
-
$date
DateTime
2022-05-05T12:00:12Z
DateTime
Instant
push
@b
Instant
loop
输入示例 1:
20220505,12:00:12,user,dept
20220505,12:00:25,user,dept
20220505,12:00:32,user,dept
示例输出1:
13
7
使用日期和时间的优点如下ISO 8601
:正确处理从一个日期到下一个日期的时间戳。
输入示例 2:
20220505,23:59:45,user,dept
20220506,00:00:00,user,dept
20220506,00:00:15,user,dept
示例输出 2:
15
15
https://en.wikipedia.org/wiki/ISO_8601
https://docs.raku.org/language/temporal#index-entry-Date_and_time_functions
https://raku.org