【问题标题】:use shell to iterate through a file使用 shell 遍历文件
【发布时间】:2016-11-26 20:37:07
【问题描述】:

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

我想出了命令: 对于 $(cat namelist) 中的单词;回声 $word;完毕 但这仅用于迭代一个文件。 我想做的是这样的:

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

【问题讨论】:

  • 我不确定我是否理解这个问题,但您可能正在寻找join 实用程序。
  • 我现在正在研究这个实用程序。谢谢!而且我只是添加了进一步的解释
  • 如果您包含 small 示例数据(3 列值得听起来应该就足够了),并且需要从该数据中输出,那么会更容易为您提供帮助。在突出显示的文本上使用编辑框左上角的{} 格式工具将格式设置为代码/数据/输出/ErrMsgs。祝你好运。
  • 另外,您的项目听起来像是为数据库设计的。如果你是为企业做这件事,那肯定是长期的解决方案。祝你好运。
  • 刚刚添加。请让我知道我是否可以展示更多内容以使其更清楚!是的,这是一个类似业务的数据库,所以我必须确保解决方案是长期的

标签: linux perl shell awk command-line


【解决方案1】:

我认为这就是您想要的(将 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

我花了很多时间试图弄清楚为什么它们不同,但我无法。抱歉,希望对您有所帮助。

【讨论】:

    【解决方案2】:

    我从你的问题中了解到,我通过这段代码使用 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";
        }
    }
    

    输入文件:

    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
    

    希望这会有所帮助。

    【讨论】:

    • 现在我认为如果超过 60 分钟,您只需将分钟转换为小时。
    猜你喜欢
    • 2016-02-10
    • 1970-01-01
    • 2011-03-21
    • 2012-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多