根据另一行中的值查找feild的最大值

时间:2017-03-19 13:32:44

标签: bash awk sed

我有一个如下文件(示例代码段),我想找出花费最长时间的任务,时间字段不必立即跟随任务字段。

task: a
time:10
log: akjafgasgf
...
....
task:b

log: taskb
.....
time:30
....
....

task:c
time:20
....
....
log:hhhhs

以上输入的示例输出是     任务:b时间:30

我试过了

awk -F":" '/task/{i=$2}{if($0 ~ "time" ) arr[i]=$2}END{for(i in arr) print i,arr[i]}'  filename  | sort -nr -k2,2  | head -n1

它有效,但我认为这可以更优化,所以请提供比这更好的建议。

4 个答案:

答案 0 :(得分:2)

你可以这样做:

awk -F: '
  $1=="task" { ct = $2 }
  $1=="time" { if($2 > mti){ mti = $2; mta = ct }  }
  END        { printf("task:%s time:%s\n",mta, mti) }
' yourfile
  • :用作分隔符(-F:
  • 当前任务存储在ct,这意味着我们需要之前时间线
  • 当我们看到time行时,$2中的值与目前为止看到的最大时间值进行比较;如有必要,mtimta会更新
  • END中打印最大值

答案 1 :(得分:1)

批发解决方案,假定任务先于时间并且一对一。

awk -F' *: *' '$1=="task" {n=$2} 
               $1=="time" {t[n]=$2} 
               END        {for(n in t) print n,t[n]}' file | 
sort -k2nr

将给出

b 30
c 20
a 10

请注意字段分隔符周围的空白处理,如第一个任务中所示。您当然可以使用索引数组在awk中进行排序,但该工具已经存在。

答案 2 :(得分:0)

Perl :)(也为给定任务多次求和)

MongoDB shell version: 3.2.12
connecting to: admin
2017-03-19T13:52:52.591+0000 I NETWORK  [initandlisten] connection accepted from 127.0.0.1:45052 #1 (1 connection now open)
2017-03-19T13:52:52.591+0000 I ACCESS   [conn1] note: no users configured in admin.system.users, allowing localhost access
Successfully added user: {
    "user" : "rootUser",
    "roles" : [
        {
            "role" : "root",
            "db" : "admin"
        }
    ]
}
2017-03-19T13:52:52.617+0000 I NETWORK  [conn1] end connection 127.0.0.1:45052 (0 connections now open)
MongoDB shell version: 3.2.12
connecting to: admin
2017-03-19T13:52:52.650+0000 I NETWORK  [initandlisten] connection accepted from 127.0.0.1:45054 #2 (1 connection now open)
2017-03-19T13:52:52.663+0000 I ACCESS   [conn2] Successfully authenticated as principal rootUser on admin
switched to db admin
Successfully added user: {
    "user" : "testuser",
    "roles" : [
        {
            "role" : "dbOwner",
            "db" : "Mongotest"
        }
    ]
}
bye
2017-03-19T13:52:52.677+0000 I NETWORK  [conn2] end connection 127.0.0.1:45054 (0 connections now open)

输出

perl -nlE '
    $t = $1        if /^task:\s*(.*)/;
    $s->{$t} += $1 if /^time:\s*(.*)/;
    }{
    say "$_: $s->{$_}" for sort { $s->{$b} <=> $s->{$a} } keys %$s
' tasks.txt

b: 30
c: 20
a: 10

输出

perl -nlE '
        $t = $1        if /^task:\s*(.*)/;
        $s->{$t} += $1 if /^time:\s*(.*)/;
        }{
        say "$_: $s->{$_}" for [sort { $s->{$b} <=> $s->{$a} } keys %$s]->[0]
' tasks.txt

更多更好地使用一个漂亮的,功能齐全的perl脚本而不是这种hackish“multiliner”。但是YMMV - 你可以随时将它挤进一条不可读的线,如:

b: 30

答案 3 :(得分:0)

awk -F: '/^task/{ta=$0} /^time/&&($2>ti||ti==""){ti=$2;b=ta OFS $0} END{print b}' file
task:b time:30

说明:

awk -F: '                         # set delimiter
/^task/ { ta=$0 }                 # buffer task record
/^time/ && ( $2>ti || ti=="" ) {  # if time value larger than previous max
    ti=$2                         # store new max time value
    b=ta OFS $0                   # construct ouput buffer while at it
} 
END {
    print b                       # output max
}' file