以下是我的输入文件:
数据是分钟的。
我需要通过对每个分钟块进行求和来将数据转换为分钟数,即[1-5,6-10等]。我需要这些数据在jfree图表中绘制。请建议如何获得输出
输入:
11.01:5
11.02:4
11.03:3
11.04:8
11.05:2
12.11:3
12.12:4
12.13:1
12.15:0
13.03:04
22.56:01
22.57:03
22.58:2
23.00:0
输出:
11.05:22
12.15:8
13.05:4
23.00:6
答案 0 :(得分:1)
这个awk应该可以工作:
awk -F '[.:,]' -v OFS=: '{
p=5*int(($2+4)/5);
$1=1*$1;
if(p==60){
p="0";
$1++
}
k=sprintf("%02d.%02d", $1, p)
}
!s[k]{
b[++n]=k
}
{
s[k]+=$3
}
END{
for (i=1; i<=n; i++)
print b[i],s[b[i]]
}' file
11.05:22
12.15:8
13.05:4
23.00:6
答案 1 :(得分:1)
这是草稿。一旦你展示了一些尝试,我将提供更通用的方法:
awk -F"[.:]" -v OFS=":" '{r=sprintf("%d", ($2-1)/5); r=(r+1)*5; a[$1"."r]+=$3} END {for (i in a) print i, a[i]}' file
对于您的给定输入,它返回:
22.60:6
13.5:4
12.15:8
23.5:0
11.5:22
关键是要将每1,2,3,4和5映射到5.我这样说:
d -> d-1 -> (d-1)/5 (int division) -> (d-1)/5 * 5
要确保没有出现分钟60
,您可以添加一些条件:if (r==60) {r=0; $1++}
:
$ awk -F"[.:]" -v OFS=":" '{r=sprintf("%d", ($2-1)/5); r=(r+1)*5; if (r==60) {r=0; $1++}; a[$1"."r]+=$3} END {for (i in a) print i, a[i]}' file
23.0:6
13.5:4
12.15:8
23.5:0
11.5:22
你也可以做一些奇特的事情,比如打印领先的0
几分钟&lt; 10,然后打印那些总和为&gt; 0的值:
$ awk -F"[.:]" -v OFS=":" '{r=sprintf("%d", ($2-1)/5); r=(r+1)*5; if (r==60) {r=0; $1++}; r=sprintf("%02d", r); a[$1"."r]+=$3} END {for (i in a) if (a[i]) print i, a[i]}' file
11.05:22
12.15:8
13.05:4
23.00:6
答案 2 :(得分:0)
这个问题可以通过百万种不同的方式解决:sed,awk,python等。
以下是使用常见bash命令执行此操作的方法。
#!/bin/bash
# extract the unique set of hours from the input (i.e. 11, 12, 13, 22, 23)
#
hours=$(cut -f 1 -d . test.txt | sort -u)
for hour in $hours; do
# initialize sum for this hour
#
count=0
# extract the number following the ':'
#
for x in $(grep "^$hour" test.txt | cut -f 2 -d :); do
# sum up the numbers following the ':'
#
count=$(($count + $x))
done
# Extract the last timestamp for the given hour
#
t=$(grep "^$hour" test.txt | tail -1 | cut -f 1 -d :)
# Print the desired output of timestamp:sum
#
echo $t:$count
done
这是输出:
11.05:22
12.15:8
13.03:4
22.58:6
23.00:0
您的输入存储在test.txt文件中:
11.01:5
11.02:4
11.03:3
11.04:8
11.05:2
12.11:3
12.12:4
12.13:1
12.15:0
13.03:04
22.56:01
22.57:03
22.58:2
23.00:0
让我指出你在脚本中看到的一些命令
cut
用于从输入中提取列。 cut -f 1 -d .
将从您的输入中提取小时。 -f 1
表示打印列1和-d .
表示使用&#39;。&#39;作为分遣者。tail -f 1
打印尾部输入的最后一行。sort -u
从输入中删除重复行。答案 3 :(得分:0)
再多一次awk
如果要舍入到最接近的5
awk -F"[.:]" '{$2=(t=($2%5))>2?$2-t+5:$2-t;if($2==60){$1++;$2=0};a[$1]+=$3;b[$1]=$2}
END{for(i in b)print i"."b[i]":"a[i]}' file
如果你想要整理不是5的倍数的所有内容。
awk -F"[.:]" '{$2=$2%5!=0?$2-($2%5)+5:$2;if($2==60){$1++;$2=0};a[$1]+=$3;b[$1]=$2}
END{for(i in b)print i"."b[i]":"a[i]}' file
11.5:22
12.15:8
22.55:4
13.5:4
23.0:2
11.05:22
12.15:8
13.5:4
23.00:6
正如你在输出中看到的那样,它将四舍五入到最接近的5,这就是22.55存在的原因
当数字除以另一个
时,模数给出余数 24/5 = 4 remainder 4
所以
24%5 = 4
因此,要将数字向下舍入到X的下一个倍数,我们只需要减去余数,这样
N-(N%X)
24-(24%5)
始终是X
的倍数(向下舍入)。
为了向上舍入,我们简单地说模数的结果是否超过X
的一半(在这种情况下为5),然后将X添加到结果中以舍入到X的下一个倍数
(N-(N%X))+X
(24-(24%5))+5
不确定这是否是最佳的圆形方式,但它有效:)