我有一个包含5个内容字段的文件。我在文件中一次评估4行。因此,记录1-4被评估为一组。记录5-8是另一组。在每组中,当字段4具有最大值时,我想从字段5中提取时间。如果字段4中存在重复值,则评估字段2中的最大值,并使用字段5中与字段2中的最大值相关的时间。
例如,在前4条记录中,字段4中有一个重复的最大值(值53(。如果这是真的,我需要查看字段2并找到最大值。然后用字段5中的时间打印字段2中与最大值相关的时间。
The Data Set is:
00 31444 8.7 24 00:04:32
00 44574 12.4 25 00:01:41
00 74984 20.8 53 00:02:22
00 84465 23.5 53 00:12:33
01 34748 9.7 38 01:59:28
01 44471 12.4 37 01:55:29
01 74280 20.6 58 01:10:24
01 80673 22.4 53 01:55:49
记录1到4所需的输出为00:12:33记录5至8的期望输出为01:10:24
这是我的答案:
评估记录1至4
awk’NR==1,NR===4{如果(max<=$4({max=$4;time=$5}否则如果(max===$4;next}END{print time}'test.txt test.txt
输出为:00:12:33
评估记录5至8
awk’NR==5,NR===8{如果(max<=$4({最大=$4;时间=$5}否则如果(max==$4({最大=$2;时间=5};next}END{print time}'test.txt test.txt
输出为01:10:24
关于如何在不必为每组记录编写awk语句的情况下更有效地评估记录范围,有什么建议吗?
感谢
根据您的样本输入,每个键(第一个字段(有4行似乎无关紧要,您真正想要的是只为每个键产生输出,所以请考虑按您想要的比较字段(字段4,然后字段2(对输入进行排序,然后按每个键打印每个块(字段1(看到的第一个想要的输出(字段5(值:
$ sort -n -k1,1 -k4,4r -k2,2r file | awk '!seen[$1]++{print $5}'
00:12:33
01:10:24
这个awk代码
NR % 4 == 1 {max4 = $4; max2 = $2}
$4 > max4 || $4 == max4 && $2 >= max2 {max4 = $4; max2 = $2; val5 = $5}
NR % 4 == 0 {printf "lines %d-%d: %sn", (NR - 3), NR, val5}
输出
lines 1-4: 00:12:33
lines 5-8: 01:10:24
查看数据,您可能希望按$1对集合进行分组,而不是硬编码4行:
awk '
function emit(nr) {printf "lines %d-%d: %sn", nr - 3, nr, val5}
$1 != setId {
if (NR > 1) emit(NR - 1)
setId = $1
max4 = $4
max2 = $2
}
$4 > max4 || $4 == max4 && $2 >= max2 {max4 = $4; max2 = $2; val5 = $5}
END {emit(NR)}
' data
一种基于awk
的解决方案,该解决方案利用组合$4
和$5
的合成ascii
字符串比较密钥,同时避免任何%-modulo
操作:
mawk '
BEGIN { CONVFMT = "%020.f" (__=___=____=_____="")
_+=_+=++_ } { ____= __!=(__=__==$((_____=(+$_ "")"(" $NF)^!_)
? __ : $!!_) || ____<_____ ? _____ : ____
} _==++___ {
printf(" group %-*s [%*.f, %-*.f] :: %sn", --_*--_, """ (__) """, _+_,
NR-++_, ++_, NR, substr(____, index(____, "(")+_^(_____=____=___=""))) }'
group "00" [ 1, 4 ] :: 00:12:33
group "01" [ 5, 8 ] :: 01:10:24