-1

我有一个这样的文本文件:

A   B   C   D   E
----------------------  
x   x   e   2   10
y   y   g   1   8 
z   o   e   2   9 
o   o   q   1   10
p   z   e   3   22
x   x   e   1   11
z   o   a   1   24
y   z   b   1   25

我想用awk做同样的事情SQL

select A, 
       B, 
       count(distinct C), 
       sum(D),
       sum(case when E>20 then E else 0 END) 
  from test 
 group by A,B

输出:

A   B  count(distinct C)    sum(D)  sum(case when E>20 then E else 0 END) 
-------------------------------------------------------
o   o   1       1       0
p   z   1       3       22
x   x   1       3       0
y   y   1       1       0
y   z   1       1       25
z   o   2       3       24

这是我的解决方案,但不同的部分尚未完成:

awk '
{
    idx4[$1"|"$2]=idx4[$1"|"$2]+$4;
    idx5[$1"|"$2]=$5>20?idx5[$1"|"$2]+$5:idx5[$1"|"$2]
} 
END {
    for (i in idx4) print i, idx4[i], idx5[i]
}' OFS="\t" test

==================================================== ============================

我已经完成了几个小时,这是我的代码:

    {
        if (idx3[$1"|"$2, $3] == 0) {
            idx3[$1"|"$2, $3]+=1;
        }
        idx4[$1"|"$2]=idx4[$1"|"$2]+$4;
        idx5[$1"|"$2]=$5>20?idx5[$1"|"$2]+$5:idx5[$1"|"$2]
    } 
    END {
        for (j in idx3) {
            split(j, idx, SUBSEP)
            count[idx[1]]++
        }
        for (i in idx4) {
            print i, count[i], idx4[i], idx5[i] 
        }
    } OFS="\t"

@Scrutinizer 在下面给出了更易读的代码,我认为这更好。

4

3 回答 3

1

请试试这个脚本,我已经测试过它可以像你期望的那样输出结果。

awk '
{
    if( NR<3) {next}

    idx4[$1"|"$2]=idx4[$1"|"$2]+$4;
    idx5[$1"|"$2]=$5>20?idx5[$1"|"$2]+$5:idx5[$1"|"$2]

    if( index(TR[$1"|"$2],$3)==0 )
    {
         TR[$1"|"$2] = TR[$1"|"$2]"|"$3;
         TRD[$1"|"$2] +=1;
    }
} 
END {
    for (i in idx4) print i, TRD[i], idx4[i], idx5[i]+0
}' OFS="\t" test
于 2013-03-15T05:22:34.800 回答
1

试试这个(类似于你自己的解决方案):

awk '
  NR<3{
    next
  }

  {
    i=$1 OFS $2
    D[i]+=$4
  }

  !A[i,$3]++{
    C[i]++
  }

  $5>20{
    E[i]+=$5
  }

  END{
    for(i in D)print i, C[i], D[i], E[i]+0
  }
' OFS='\t' infile

NR<3用于跳过两个标题行。如果它们不存在于输入文件中,您可以忽略该部分。

于 2013-03-14T20:10:43.250 回答
0
$ gawk '{ a[$1,$2]["C"][$3]; a[$1,$2]["D"]+=$4; a[$1,$2]["E"]+=($5>20 ? $5:0) }
END { 
    PROCINFO["sorted_in"] = "@ind_str_asc"
    for ( i in a) { 
        split(i, b, SUBSEP) 
        print b[1], b[2], length(a[i]["C"]), a[i]["D"], a[i]["E"] 
    }
}' OFS='\t' file
o       o       1       1       0
p       z       1       3       22
x       x       1       3       0
y       y       1       1       0
y       z       1       1       25
z       o       2       3       24
于 2017-06-24T05:56:48.223 回答