【问题标题】:Check a value's statistics in a column using bash使用 bash 检查列中值的统计信息
【发布时间】:2014-03-17 23:31:52
【问题描述】:

我有文件calls.txt。它有 7 个字段:

Date|time|duration|callee|caller|calleeLocation|callerLocation
01/01/2005|15:55:27|495|10000075|10000029|29|4
01/01/2005|11:04:00|597|10000064|10000078|25|4
01/01/2005|08:44:06|593|10000070|10000107|1|7
01/01/2005|18:35:19|235|10000017|10000036|7|14

我想要一些帮助我做以下方法:

  • 这将打印比其他任何人都呼叫 10000027 的呼叫者

  • 这将使呼叫 10000027 的呼叫者比其他任何人都长(使用持续时间字段)。

  • 10000027 在 2005 年 4 月 1 日到 2005 年 4 月 31 日之间拨打了多少电话

我尝试了一些方法,但它们并没有达到我想要的效果。这是我的代码:

#!/bin/bash
exec 401<> calls.txt 
while read line <&401      # read a line at a time from calls.txt
do                         # if end of file reached, while will yield false the$
{

full_line=$line;       # because $line is going to change, store it somewhe$


    date=${line%%|*}; # cut off the rest of $line but keep date 
    line=${line#*|};       


    time=${line%%|*}; # cut off the rest of $line but keep time
    line=${line#*|};       

    duration=${line%%|*};  # cut off the rest of $line but keep box
    line=${line#*|};       



    callee=${line%%|*};   # cut off the rest of $line but keep callee
    line=${line#*|};      



    caller=${line%%|*};   # cut off the rest of $line but keep caller
    line=${line#*|};      


    calleeLoc=${line%%|*};   # cut off the rest of $line but keep callee location
    line=${line#*|};


    callerLoc=${line%%|*};   # cut off the rest of $line but keep caller location
    line=${line#*|};

这个方法应该打印最多调用10000027的调用者

    if [ $callee = 10000027 ]
     then  
       count= $(grep -cw $caller {callee}calls.txt
              if [[ $max_count -le $count ]] 
                 then
                max_count=$count;
                most_caller=$caller;
              fi
   fi  

我怎样才能修改这个方法,让它打印出呼叫者中持续时间最长的呼叫者 10000027

 if [ $callee = 10000027 ]
     then  
       count= $(grep -cw $caller {callee}calls.txt
              if [[ $max_count -le $count ]] 
                 then
                duration=$count;
                longest_caller=$caller;
              fi
   fi  

如何修改此方法,以便打印 10000027 在 2005 年 4 月 1 日至 2005 年 4 月 31 日之间进行了多少次调用

   if [ $caller = 10000027 ];
      then

            if [ $date -gt (1/4/2005) && $date -lt (31/4/2005) ];

                  $awk '$4~/10000027/{++c} END{ print c} 'FS=:calls.txt

            fi
    fi



}
done


exec 401>&-

【问题讨论】:

  • 你能正确指定你想要什么吗?因为根据您对方法的描述,我无法得到您真正想要的。
  • @jayesh 我需要三种方法的帮助。 1)第一个方法应该打印调用 10000027 的 callerId 比任何其他 callerID 多 2)第二个方法应该打印调用 10000027 的 callerId 比任何其他 callerID 长(使用持续时间字段) 3)第三种方法应该打印10000027 在 2005 年 4 月 1 日至 31 日期间拨打的电话
  • 您必须为此使用外壳处理吗? awk 或 perl 更适合这类问题。如果您必须使用 shell,请查看 while 循环如何解析 stackoverflow.com/questions/22384076/… 解决方案中的所有 var 名称。您必须添加 IFS="|"为您的数据。祝你好运。
  • 如果您希望我们花时间帮助您,请格式化您的代码以使其可读,并准确解释它没有正确执行的地方。

标签: linux bash awk delimiter do-while


【解决方案1】:

你可以试试:

awk -f a.awk calls.txt

a.awk 在哪里:

BEGIN {FS="|"; num="10000027"}
{
    if ($4==num) a[$5]++
}

END {
    max=0;
    for (i in a) {
        if (a[i]>max) {
            max=a[i]
            c=i;
        }
    }
    print "Caller: "c" called "num" "max" times."
}

输出:

Caller: 10000093 called 10000027 9 times.

【讨论】:

  • @tonto 太好了 :) 你能解决其他问题吗?问问你是否卡住了..
  • 你能帮我解决其他问题吗?我如何将 a.awk 等同于下面的代码?
  • @tonto 嗨。你想总结所有的持续时间,还是只想检查给定的持续时间是否最大?例如,如果呼叫者 10000093 呼叫 10000027 一次 800 秒,一次呼叫 600 秒。你想把这些相加,还是只检查 800 秒是否是最大的?
  • 我想遍历所有拨打 10000027 的持续时间并获得最高持续时间的人
  • @tonto 所以你想总结所有通话的持续时间?您不是在寻找一个最长的呼叫,而是在寻找他对给定号码进行的所有呼叫的持续时间总和在不同呼叫者中最大的呼叫者?
【解决方案2】:

这是一条评论,但格式化 cmets 很难,所以我使用的是答案框。使用 read 读取输入要容易得多:

while IFS=\| read Date time duration callee caller calleeLocation callerLocation
do
 ...
done < input-file

将为您完成所有任务,您可以避免正在执行的解析。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-14
    • 1970-01-01
    • 2011-02-03
    • 2020-03-19
    • 1970-01-01
    • 2011-05-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多