Select 列基于行值

Select column based on the row value

我有这样的文件(制表符分隔)

Name  Data1  Data2  Extra  A   B   C   D  
Test1   A     C       40   23  10  12  5  
Test2   B     C       20   13  3   32  5  
Test3   C     D       44   43  0   1   5  
Test4   A     D       43   2   7   0   5  

我需要根据这个数据 1 和数据 2 添加名为频率的列。 Freq= Data2值/(Data2值+Data1值)。例如对于 Test1 Freq = 12/(12+23)

像这样计算和添加值将很容易(对于 Data1="A" 和 Date2="C" 的行

  awk '{print/(+)}‘

但是我如何 select 基于行值的列?

预计结束

Name  Data1  Data2  Extra  A   B   C   D  Freq
Test1   A     C       40   23  10  12  5  0.34
Test2   B     C       20   13  3   32  5  0.91
Test3   C     D       44   43  0   1   5  0.83
Test4   A     D       43   2   7   0   5  0.71

根据 Data1 的值获取副本:

gawk '{ 
   s=(=="A"?5:0)+(=="B"?6:0)+(=="C"?7:0)+(=="D"?8:0); 
   print [=10=],s,(s!=0?$s:"") '}   inputfile

通过您的示例输入,可以得到:

Name  Data1  Data2  Extra  A   B   C   D 0
Test1   A     C       40   23  10  12  5 5 23
Test2   B     C       20   13  3   32  5 6 3
Test3   C     D       44   43  0   0   5 7 0
Test4   A     D       43   0   7   0   5 5 0

s 的值引用该列,因此 $s 给出该列的值。

顺便说一句:我正在使用 gawk,但这也适用于 awk

$ cat tst.awk
BEGIN { FS=OFS="\t" }
NR==1 {
    $(NF+1) = "Freq"
    for (i=1; i<=NF; i++) {
        f[$i] = i
    }
    print
    next
}
{
    d1 = $(f["Data1"])
    d2 = $(f["Data2"])
    numer = $(f[d2])
    denom = numer + $(f[d1])
    $(f["Freq"]) = sprintf( "%.02f", (denom ? numer / denom : 0) )
    print
}

$ awk -f tst.awk file
Name    Data1   Data2   Extra   A       B       C       D       Freq
Test1   A       C       40      23      10      12      5       0.34
Test2   B       C       20      13      3       32      5       0.91
Test3   C       D       44      43      0       1       5       0.83
Test4   A       D       43      2       7       0       5       0.71

这样的东西可能对你有用,我写得有点冗长,强调正在发生的事情:

$ cat freq_from_col.awk 
function indirect(val) {
        if (val == "A")
                return $col_a
        if (val == "B")
                return $col_b
        if (val == "C")
                return $col_c
        if (val == "D")
                return $col_d

        return 0
}
BEGIN {
        col_name = 1
        col_data1 = 2
        col_data2 = 3
        col_extra = 4
        col_a = 5
        col_b = 6
        col_c = 7
        col_d = 8
}
NR == 1 {
        print [=10=], "Freq"
        next;
}
{
        n = indirect($col_data1);
        m = indirect($col_data2);

        print [=10=], sprintf("%.2f", m/(n+m));
}
$ awk -f freq_from_col.awk data.txt
Name  Data1  Data2  Extra  A   B   C   D Freq
Test1   A     C       40   23  10  12  5 0.34
Test2   B     C       20   13  3   32  5 0.91
Test3   C     D       44   43  0   1   5 0.83
Test4   A     D       43   2   7   0   5 0.71