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
我有这样的文件(制表符分隔)
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