使用shell迭代文件

时间:2016-07-22 20:42:06

标签: linux perl shell awk command-line

我有两个输入文件。一个有名单,mm:dd形式,使用持续时间和每行中的其他主机名。另一个是我生成的那个,每行中都有一组不重复的名单。 我正在尝试编写一个shell命令来遍历带有namelist的文件,将它们存储为变量并检查其他文件以匹配名称,然后输出每个人的总使用时间,然后输出包含和信息。无论如何我可以用awk或其他任何东西来做这项工作吗?

我想到了这个命令: $(猫名单);回声$ word; DONE 但这仅适用于迭代一个文件。 我想做的是这样的事情:

for word in namelist.txt:
 for words in info_file.txt (field $1):
   if word == words:
     (calculating usage of time) 
     print(word, ':', usage of time)

我已经找出了计算时间使用的代码。这就是如何做这个操作,这是我现在的问题。 有人可以帮忙吗?

-----------------进一步解释 所以我有一个文件,其中包含用户登录主机所消耗的时间信息,每行有名称,日期(mm:dd:hh:mm),初始时间,结束时间,持续时间和主机名信息。 我想要实现的是输出一个文件,每个月作为标题(例如:[April]),然后计算登录主机的每个用户的持续时间。它们可能具有多次登录,因此它们的名称会在每行中显示多次其他信息。我生成了这个文件,其中包含过去半年内登录过的所有用户名。我正在尝试使用每个月份名称作为标题生成输出文件,并逐月分组,然后将文件中的名称与我生成的名称列表进行匹配,以计算他们的持续时间并将其打印到同一行的输出文件中他们的名字印了。我已经想出了如何进行计算。所以现在我只是如何进行匹配让我感到困惑的名字的步骤

输入文件:

sdou     pts/11       Thu Dec 10 05:24 - 12:11 (2+06:46)    131.243.186.99
sdou     pts/10       Thu Dec 10 05:04 - 12:11 (2+07:06)    131.243.186.99
sdou     pts/9        Thu Dec 10 03:26 - 12:11 (2+08:45)    131.243.186.99
ermartin pts/0        Sat Dec 12 12:37 - 13:44  (01:06)     c-24-130-14-154.hsd1.ca.comcast.net
ermartin pts/0        Sat Dec 12 12:18 - 12:31  (00:13)     c-24-130-14-154.hsd1.ca.comcast.net

示例输出:

[Dec]
sdou 94.xxxhours
ermartin 1.19hours

2 个答案:

答案 0 :(得分:2)

我认为这就是你想要的(使用GNU awk 4. *来表示真正的多维数组):

$ cat tst.awk
{
    n = split($9,t,/[()+:]/)
    hours = t[n-3]*24 + t[n-2] + t[n-1]/60
    tot[$4][$1] += hours
}
END {
    for (month in tot) {
        print "["month"]"
        for (user in tot[month]) {
            print user, tot[month][user] "hours"
        }
    }
}

$ awk -f tst.awk file
[Dec]
sdou 166.617hours
ermartin 1.31667hours

但输出数字与您的预期值不符:

[Dec]
sdou 94.xxxhours
ermartin 1.19hours

我花了很多时间试图弄清楚他们为什么会有所不同,但我无法做到。对不起,希望无论如何都有帮助。

答案 1 :(得分:-1)

我通过这段代码使用perl解决了这个问题。我从你的问题中了解到这一点。

#!/usr/bin/perl -w
use strict;
use warnings;

use Data::Dumper;   # $fields[3] => Month $fields[0] => user $fields[8] => Time

my $user_time = {};
my $time = {};
open my $READ , '<', 'test' or die;

while(my $line = <$READ>){
    my @fields = split(' ', $line);

    my $user = $fields[0];
    my $month = $fields[3];

    $fields[8] =~ m/([\d]*)\+?([\d]{2}):([\d]{2})/; #time format
    my $min = $3;
    my $hr = $2;
    my $day = $1;
    $day = 0 if (!$day);
    if (!exists $user_time->{$month}->{$user}){
        $time = {};
    }
    $time->{'day'} += $day*24;
    $time->{'hr'} += $hr;
    $time->{'min'} += $min;

    $user_time->{$month}->{$user} = $time;
}
close $READ;
foreach my $month (keys %$user_time){
    print "[$month]\n";
    my $user_hash = $user_time->{$month};
    foreach my $user (keys %$user_hash){
        my $time = $user_hash->{$user};
        print "$user\t". $time->{'day'}.'.'.$time->{'hr'}.'.'.$time->{'min'}."hours\n";
    }
}

INPUT FILE:

sdou     pts/11       Thu Dec 10 05:24 - 12:11 (2+06:46)    131.243.186.99
sdou     pts/10       Thu Dec 10 05:04 - 12:11 (2+07:06)    131.243.186.99
sdou     pts/9        Thu Dec 10 03:26 - 12:11 (2+08:45)    131.243.186.99
ermartin pts/0        Sat Dec 12 12:37 - 13:44  (01:06)     c-24-130-14-154.hsd1.ca.comcast.net
ermartin pts/0        Sat Dec 12 12:18 - 12:31  (00:13)     c-24-130-14-154.hsd1.ca.comcast.net

<强>输出:

[Dec]
ermartin 0.1.19hours
sdou     144.21.97hours

希望这有帮助。