【问题标题】:awk count and sum based on slab:基于slab的awk计数和总和:
【发布时间】:2014-06-28 06:12:37
【问题描述】:

如果第一个文件的第 4 个字段在 第二个文件 (Slab.csv) 第一个字段 (Start Range) 和第二个字段 (End Range) 然后填充 Slab 明智的行数以及第一个文件的第 4 和第 5 字段的总和。

Input.csv.gz (GunZip)

Desc,Date,Zone,Duration,Calls
AB,01-06-2014,XYZ,450,3
AB,01-06-2014,XYZ,642,3
AB,01-06-2014,XYZ,0,0
AB,01-06-2014,XYZ,205,3
AB,01-06-2014,XYZ,98,1
AB,01-06-2014,XYZ,455,1
AB,01-06-2014,XYZ,120,1
AB,01-06-2014,XYZ,0,0
AB,01-06-2014,XYZ,193,1
AB,01-06-2014,XYZ,0,0
AB,01-06-2014,XYZ,161,2

Slab.csv

StartRange,EndRange
0,0
1,10
11,100
101,200
201,300
301,400
401,500
501,10000

预期输出:

StartRange,EndRange,Count,Sum-4,Sum-5
0,0,3,0,0
1,10,NotFound,NotFound,NotFound
11,100,1,98,1
101,200,3,474,4
201,300,1,205,3
301,400,NotFound,NotFound,NotFound
401,500,2,905,4
501,10000,1,642,3

我正在使用以下两个命令来获得上述输出,期待“未找到”的情况。

awk -F, 'NR==FNR{s[NR]=$1;e[NR]=$2;c[NR]=$0;n++;next} {for(i=1;i<=n;i++) if($4>=s[i]&&$4<=e[i]) {print $0,","c[i];break}}' Slab.csv <(gzip -dc Input.csv.gz) >Op_step1.csv
cat Op_step1.csv | awk -F, '{key=$6","$7;++a[key];b[key]=b[key]+$4;c[key]=c[key]+$5} END{for(i in a)print i","a[i]","b[i]","c[i]}' >Op_step2.csv

Op_step2.csv

101,200,3,474,4
501,10000,1,642,3
0,0,3,0,0
401,500,2,905,4
11,100,1,98,1
201,300,1,205,3

任何建议使其成为实现预期输出的线性命令,不要有 perl ,python 访问。

【问题讨论】:

    标签: unix awk


    【解决方案1】:

    这是使用perl 的另一个选项,它利用创建多维数组和散列的好处。

    perl -F, -lane'
    BEGIN {
        $x = pop; 
        ## Create array of arrays from start and end ranges
        ## $range = ( [0,0] , [1,10] ... )
        (undef, @range)= map { chomp; [split /,/] } <>; 
        @ARGV = $x;
    }
    ## Skip the first line
    next if $. ==1; 
    ## Create hash of hash
    ## $line = '[0,0]' => { "count" => counts , "sum4" => sum_of_col4 , "sum5" => sum_of_col5 }
    for (@range) { 
      if ($F[3] >= $_->[0] && $F[3] <= $_->[1]) { 
        $line{"@$_"}{"count"}++; 
        $line{"@$_"}{"sum4"} +=$F[3]; 
        $line{"@$_"}{"sum5"} +=$F[4];
      } 
    } 
    }{ 
      print "StartRange,EndRange,Count,Sum-4,Sum-5"; 
      print join ",", @$_, 
      $line{"@$_"}{"count"} //"NotFound",  
      $line{"@$_"}{"sum4"}  //"NotFound", 
      $line{"@$_"}{"sum5"}  //"NotFound" 
        for @range
    ' slab input
    StartRange,EndRange,Count,Sum-4,Sum-5
    0,0,3,0,0
    1,10,NotFound,NotFound,NotFound
    11,100,1,98,1
    101,200,3,474,4
    201,300,1,205,3
    301,400,NotFound,NotFound,NotFound
    401,500,2,905,4
    501,10000,1,642,3
    

    【讨论】:

    • 非常感谢@mpapec。很棒的反馈。 // 似乎不适用于我古老的perl 工作(5.8.8)。会在家里测试一下。非常感谢.. 非常感谢:).
    • 检查plenv,您的主文件夹中可以有 v5.20 或任何其他版本。 github.com/tokuhirom/plenv
    • 感谢@mpapec 提供链接。我以前曾在 local::lib 上苦苦挣扎。下周会试试这个。
    【解决方案2】:

    这是使用awksort 的一种方式:

    awk '
    BEGIN { 
        FS = OFS = SUBSEP = ",";
        print "StartRange,EndRange,Count,Sum-4,Sum-5" 
    } 
    FNR == 1 { next }
    NR == FNR {
        ranges[$1,$2]++;
        next
    }
    {
        for (range in ranges) {
            split(range, tmp, SUBSEP); 
            if ($4 >= tmp[1] && $4 <= tmp[2]) {
                count[range]++;
                sum4[range]+=$4;
                sum5[range]+=$5; 
                next
            }
        }
    }
    END {
        for(range in ranges) 
            print range, (count[range]?count[range]:"NotFound"), (sum4[range]?sum4[range]:"NotFound"), (sum5[range]?sum5[range]:"NotFound") | "sort -t, -nk1,2"
    }' slab input
    StartRange,EndRange,Count,Sum-4,Sum-5
    0,0,3,NotFound,NotFound
    1,10,NotFound,NotFound,NotFound
    11,100,1,98,1
    101,200,3,474,4
    201,300,1,205,3
    301,400,NotFound,NotFound,NotFound
    401,500,2,905,4
    501,10000,1,642,3
    
    • 将输入、输出字段分隔符和SUBSEP 设置为,。打印标题行。
    • 如果是第一行,请跳过它。
    • 将整个slab.txt 加载到一个名为ranges 的数组中。
    • 对于ranges 数组中的每个范围,拆分字段以获得开始和结束范围。如果第 4 列在范围内,则递增计数数组并将值适当地添加到 sum4sum5 数组。
    • END 块中,遍历范围并打印它们。
    • 将输出传送到sort 以按顺序获取输出。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多