Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
bash和分组循环_Bash_Loops_Awk_Grouping - Fatal编程技术网

bash和分组循环

bash和分组循环,bash,loops,awk,grouping,Bash,Loops,Awk,Grouping,我有一个格式为的帮助文件1: client1 bla blahblah 2542 KB client1 bla blahblah 4342 MB client1 bla blahblah 7 GB client2 bla blahblah 455 MB client2 bla blahblah 455 MB 我需要做一周的工作 client1 SUM xy KB client2 SUM yx KB 当前我正在使用: sumfunction () { inputf

我有一个格式为的帮助文件1:

client1 bla blahblah 2542 KB
client1 bla blahblah 4342 MB
client1 bla blahblah    7 GB

client2 bla blahblah  455 MB
client2 bla blahblah  455 MB

我需要做一周的工作

client1 SUM xy KB
client2 SUM yx KB
当前我正在使用:

sumfunction ()
    {
    inputfile=helpfile1

    for i in `awk -F":" '{print $1}' $inputfile| sort -u | xargs`
    do
    awk -v name=$i 'BEGIN {sum=0};
    $0~name {
    print $0;
    if ($5 == "GB") sum = sum + $4*1024*1024;
    if ($5 == "MB") sum = sum + $4*1024;
    if ($5 == "KB") sum = sum + $4};
    END {print name " SUM " sum " kB"}' $inputfile
    done
    }   

sumfunction | grep SUM | sort -g -r -k 3 > weeklysize

我需要在相当长的文件中使用它,而这个awk占用了太多的时间。是否有其他代码(仅限bash)可以更快地完成此任务?谢谢

您可以使用以下awk脚本:

awk '/MB$/{$4*=1024};/GB$/{$4*=1024*1024};{a[$1]+=$4}END{for(i in a){printf "%s %s KB\n",i, a[i]}}' a.txt 
这种格式看起来更好:

/MB$/    {$4*=1024};        # handle MB
/GB$/    {$4*=1024*1024};   # handle GB

# count KB amount for the client
{a[$1]+=$4}

END{
    for(i in a){
        printf "%s %s KB\n",i, a[i]
    }
} 
输出

client11788782 KB
客户端2 931840 KB
注:

  • 将跳过空行(
    NR{[…]}
  • 通过相应地设置
    output\u unit
    KB
    MB
    GB
    )可以配置输出单元

纯Bash(4.0+):


如何更改在
帮助文件1
中写入信息的方式?好的代码,好的问题,只是由于缺乏设置期望而受到阻碍。你说的“时间太多”是什么意思,1秒2分钟3小时4天?关于有多少“记录”(通过
wc-l tooBigFile
获得)以及您在哪种硬件上运行此功能。而2倍的速度足够好吗?e尝试从您的姓名arg中创建一个reg ex,并在行的开头锚定,然后您不会扫描整行以匹配仅在开头的内容,即。
name=“^”$1$0~name
或者为什么不干脆
$1=-name{…
祝你好运。@Sheller你确定你演的电影是对的吗?@hek2mgl:是的,我想是这样,为O.P.引用了一句话。“这个awk花了太多时间”.我喜欢你的解决方案,但谁知道OP是否会,也许它太慢了。祝大家好运;-)@Sheller Ok,明白了:)不过,我或Adrian的解决方案不应该花费太多时间,而且不,时间不是相对的;)
#!/usr/bin/awk -f

BEGIN {
    output_unit = "KB"
    modifier["KB"] = 1
    modifier["MB"] = 1024
    modifier["GB"] = 1024**2
}
NF  { sums[$1] += modifier[$5] * $4 }
END {
    for (client in sums) {
        printf "%s SUM %d %s\n", client, sums[client]/modifier[output_unit], output_unit
    }
}
$ ./t.awk t.txt
client1 SUM 11788782 KB
client2 SUM 931840 KB
declare -Ai client                  # associative array

while read c1 c2 c3 c4 c5 ; do
  if [ -n "$c5" ] ; then
    if [ $c5 = 'KB' ] ; then
      client[$c1]+=$c4
    elif [ $c5 = 'MB' ] ; then
      client[$c1]+=$c4*1024
    elif [ $c5 = 'GB' ] ; then
      client[$c1]+=$c4*1024*1024
    fi
  fi
done < "$infile"

for c in ${!client[@]}; do          # print sorted results
  printf "%s %20d KB\n" $c ${client[$c]}
done | sort  -k1
client1             11788782 KB
client2               931840 KB