输入:
70|00:00:01
70|00:00:03
180|00:00:01
180|00:00:10
180|00:00:05
必需的输出:
70|00:00:04
180|00:00:16
我有一个有效的代码,但只返回总时间。
awk -F\| '{
split($2, tm, ":");
secs += tm[3];
mins += tm[2] + int(secs / 60);
hrs += tm[1] + int(mins / 60);
secs %= 60; mins %= 60;
}
END {
printf "%d:%d:%d\n", hrs, mins, secs;
}' input
如何调整代码以按第一个字段分组?
答案 0 :(得分:2)
您可以使用多维数组并在最后进行迭代和打印:
awk -F\| '{
split($2, tm, ":");
out[$1]["secs"] += tm[3];
out[$1]["mins"] += tm[2] + int(out[$1]["secs"] / 60);
out[$1]["hrs"] += tm[1] + int(out[$1]["mins"] / 60);
out[$1]["secs"] %= 60; out[$1]["mins"] %= 60;
}
END {
for (time in out){
printf "%s|%02d:%02d:%02d\n", time, out[time]["hrs"], out[time]["mins"], out[time]["secs"];
}
}' input
我也在这里编辑了您的printf
,以便在您的时间输出中包括前导0以匹配输入。
答案 1 :(得分:2)
$ cat tst.awk
BEGIN { FS = "[|:]" }
{ sum[$1] += $4 + 60*$3 + 60*60*$2 }
END {
for (key in sum) {
secs = sum[key]
h = int(secs/(60*60))
m = int((secs - (h*60*60))/60)
s = secs % 60
printf "%s|%02d:%02d:%02d\n", key, h, m, s
}
}
$ awk -f tst.awk file
70|00:00:04
180|00:00:16
答案 2 :(得分:1)
gawk -F'[:|]' '
{
arr[$1] = arr[$1] + mktime("1970 1 1 " $2 " " $3 " " $4) + 10800
}
END {
for(i in arr)
print i strftime("|%H:%M:%S", arr[i], 1)
}' input.txt
注意:
mktime
无法以UTC格式返回结果,因此在我的情况下,将mktime
时间戳结果转换为UTC是通过增加3个小时(3600 sec * 3 = 10800
)来完成的。您应该选择您的时区值。
输入(测试复杂)
70|00:00:01
70|04:00:03
70|10:00:03
70|02:00:52
70|03:00:03
70|04:00:05
180|00:00:01
180|00:00:10
180|00:00:05
输出
70|23:01:07
180|00:00:16
答案 3 :(得分:0)
解决方案第一: :考虑到您的Input_file是按第一字段排序的,因此可能对您有帮助。
awk -F\| '
prev!=$1 && FNR>1{
printf "%d|%d:%d:%d\n", prev, hrs, mins, secs
prev=hrs=mins=secs=""
}
{
split($2, tm, ":");
secs += tm[3];
mins += tm[2] + int(secs / 60);
hrs += tm[1] + int(mins / 60);
secs %= 60; mins %= 60;
prev=$1
}
END{
if(prev){
printf "%d|%d:%d:%d\n", prev, hrs, mins, secs
}
}' Input_file
解决方案第二: :如果Input_file未按第一字段排序,则可以通过执行sort -t'|' -k1
对其进行排序,并将输出也传递给上述代码。
sort -t'|' -nk1 Input_file |
awk -F\| '
prev!=$1 && FNR>1{
printf "%d|%d:%d:%d\n", prev, hrs, mins, secs
prev=hrs=mins=secs=""
}
{
split($2, tm, ":");
secs += tm[3];
mins += tm[2] + int(secs / 60);
hrs += tm[1] + int(mins / 60);
secs %= 60; mins %= 60;
prev=$1
}
END{
if(prev){
printf "%d|%d:%d:%d\n", prev, hrs, mins, secs
}
}'