我从成对分析中得到以下数据集(第一行只是样本ID):
A B A C
1 1 1 0
1 2 1 1
1 0 1 2
我希望比较field 1
和field 2
然后field 3
和field 4
的值,以便我每次都要打印行号NR
查看我正在检查的对的1
和2
组合。
例如对于A
和B
对,我想要输出:
A B 2
对于对A
和C
,我想要输出:
A C 3
我想逐行进行,所以我可能需要代码包括:
for i in {1..3}; do
awk 'NR=="'${i}'" {code}'
done
但我不知道如何以成对的方式进行(即比较field 1
和field 2
然后field 3
和field 4
等......)。
我该怎么做?
答案 0 :(得分:4)
很难用这么小的例子说,但这可能是你想要的:
$ cat tst.awk
FNR==1 {
for (i=1;i<=NF;i++) {
name[i] = $i
}
next
}
{
for (i=1;i<NF;i+=2) {
if ( ($i == 1) && ($(i+1) == 2) ) {
print name[i], name[i+1], NR-1
}
}
}
$ awk -f tst.awk file
A B 2
A C 3
答案 1 :(得分:1)
你当然应该只运行一次脚本;没有必要更频繁地运行awk
。目前尚不清楚如何打印多个匹配项。但是,如果您在某个时间线上工作,那么输出可能会一次出现一行。
在此基础上工作,然后:
awk 'NR == 1 { for (i = 1; i < NF; i += 2)
{ cols[(i+1)/2,1] = $i; cols[(i+1)/2,2] = $(i+1); }
next
}
{ for (i = 1; i < NF; i += 2)
{ if ($i == 1 && $(i+1) == 2)
print cols[(i+1)/2,1], cols[(i+1)/2,2], NR - 1
}
}'
NR == 1
代码块捕获标题,以便可以在主打印代码中使用它们。还有很多其他方法来存储信息。另一个代码块查看数据行并检查字段对是否包含1 2
,如果匹配则打印出控制数据。因为NF是偶数,但循环数是奇数,<
比较是可以的。通常在awk
中,您使用for (i = 1; i <= NF; i++)
只需一个增量,然后<=
才能获得正确的行为。
对于您的最小数据集,这会产生:
A B 2
A C 3
对于这个更大的数据集:
A B A C
1 1 1 0
1 2 1 1
1 0 1 2
1 2 4 2
5 3 1 9
7 0 3 2
1 2 1 0
9 0 1 2
1 2 3 2
代码生成:
A B 2
A C 3
A B 4
A B 7
A C 8
A B 9