Shell - 用户列的总和

时间:2018-05-02 19:43:59

标签: shell

基本上,我有两列。第一个代表用户,第二个代表他们在服务器上花费的时间。所以我想总算每个客户端,他在服务器上花了多少分钟。

user1 21:03
user2 19:55
user3 20:09
user1 18:57
user1 19:09
user3 21:05
user4 19:57

让我说我就是这个。我知道怎么分裂,但有一个问题。每当我awk -F: '{print $1}时,它会打印用户和时间的第一个参数(:之前的数字),当我awk -F: '{print $2}时,它只打印:之后的数字。总而言之,我想得到像

这样的东西
user1 59:09
user2 19:55
user3 41:14
user4 19:57

3 个答案:

答案 0 :(得分:0)

这是一个可能的解决方案:

import React from 'react';
import {
  BrowserRouter as Router,
  Route
} from "react-router-dom";
import './App.css';
import axios from 'axios';
import Body from './Body';
import User from './User';
import Header from './Header';


class AppRouter extends React.Component {
  state = {
    employeeCurrent: [],
    employee: []
  };

  componentDidMount() {
    axios
      .get("http://127.0.0.1:3004/employee")
      .then(response => this.setState({
        employee: response.data
      }));
  }

  add = name => {
    this.setState(prevState => {
      const copy = prevState.employeeCurrent.slice(1);
      copy.push(name);
      return {
        employeeCurrent: copy
      };
    });
  };

  render() {
    return ( <
      Router >
      <
      div className = "router" >
      <
      Header / >
      <
      Route exact path = "/"
      render = {
        props => ( <
          Body { ...props
          }
          add = {
            this.add
          }
          employee = {
            this.state.employee
          }
          employeeCurrent = {
            this.state.employeeCurrent
          }
          />
        )
      }
      /> <
      Route path = "/user/:id"
      component = {
        props => ( <
          User { ...props
          }
          employee = {
            this.state.employee
          }
          employeeCurrent = {
            this.state.employeeCurrent
          }
          />
        )
      }
      /> <
      /div> <
      /Router>
    );
  }
}
export default AppRouter;

或者更好的格式化:

perl -ne '/^(\S+) (\d\d):(\d\d)$/ or next; $t{$1} += $2 * 60 + $3; END { printf "%s %02d:%02d\n", $_, $t{$_} / 60, $t{$_} % 60 for sort keys %t }'

我们遍历所有输入行(perl -ne ' /^(\S+) (\d\d):(\d\d)$/ or next; $t{$1} += $2 * 60 + $3; END { printf "%s %02d:%02d\n", $_, $t{$_} / 60, $t{$_} % 60 for sort keys %t; } ' )。我们确保每一行都匹配模式-n(即一个或多个非空格字符的序列,一个空格,两个数字,一个冒号,两个数字),否则我们会跳过它。

我们累计哈希\S+ \d\d:\d\d中每个用户的秒数。键是用户名,值是数字。

最后,我们以格式良好的方式打印%t的内容。

答案 1 :(得分:0)

这是一个awk解决方案

cat 1.txt | awk '{a[$1]+=substr($2,0,2)*60+substr($2,4)} END {for(i in a) printf("%s %02d:%02d\n", i,a[i]/60,a[i]%60)}'
user1 59:09
user2 19:55
user3 41:14
user4 19:57

首先构造一个index = $ 1的数组,value =将时间转换为整数分钟* 60 +秒

{a[$1]+=substr($2,0,2)*60+substr($2,4)}

然后以所需格式打印数组,将整数转换为mi:ss格式。

printf("%s %02d:%02d\n", i,a[i]/60,a[i]%60)

答案 2 :(得分:0)

如果你想使用awk(并假设持续时间始终是hh:mm,虽然他们的尺寸可以是任意的),但以下方法可以解决问题:

{
    split($2, flds, ":")               # Get hours and minutes.
    mins[$1] += flds[1] * 60 + flds[2] # Add to initially zero array item.
}
END {
    for (key in mins) {                # For each key in array.
        printf "%s %d:%02d\n",         # Output specific format.
            key,                       # Key, hours, and minutes.
            mins[key] / 60,
            mins[key] % 60
    }
}

这是扩展的,可读的变体,压缩的变体显示在下面的记录中,以及预期的输出:

pax> awk '{split($2,flds,":");mins[$1] += flds[1] * 60 + flds[2]}END{for(key in mins){printf "%s %d:%02d\n",key,mins[key]/60,mins[key]%60}}' testprog.in

user1 59:09
user2 19:55
user3 41:14
user4 19:57

请记住,只要用户条目超过24小时,您就没有指定输入格式。如果它类似于25:42,则脚本将按原样运行。

如果相反它决定分出日期(类似于1:01:42而不是25:42),则需要调整分钟的计算方式。这可以通过检查flds数组大小(在脚本的主体中,非{{1})相对容易地完成(包括仅分钟条目的可能性)。 }位:

END