如何比较awk中的列对?

如何比较awk中的列对?,awk,Awk,我有以下来自成对分析的数据集(第一行只是示例ID): 我希望比较字段1和字段2的值,然后比较字段3和字段4,这样每当我看到我正在检查的对的1和2组合时,我都想打印行号NR 例如,对于成对的A和B,我希望输出: A B 2 A C 3 对于成对的A和C,我希望输出: A B 2 A C 3 我希望逐行进行,因此我可能需要代码包括: for i in {1..3}; do awk 'NR=="'${i}'" {code}' done 但我不知道如何两两进行(即比较字段1和字段2,然

我有以下来自成对分析的数据集(第一行只是示例ID):

我希望比较
字段1
字段2
的值,然后比较
字段3
字段4
,这样每当我看到我正在检查的对的
1
2
组合时,我都想打印行号
NR

例如,对于成对的
A
B
,我希望输出:

A B 2
A C 3
对于成对的
A
C
,我希望输出:

A B 2
A C 3
我希望逐行进行,因此我可能需要代码包括:

for i in {1..3}; do
    awk 'NR=="'${i}'" {code}'
done
但我不知道如何两两进行(即比较
字段1
字段2
,然后比较
字段3
字段4
等)


我该怎么做呢?

您当然应该只运行一次脚本;无需更频繁地运行
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
               }
             }'
对于这个较大的数据集:

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 2
A C 3
A B 4
A B 7
A C 8
A B 9

您当然应该只运行脚本一次;无需更频繁地运行
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
               }
             }'
对于这个较大的数据集:

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 2
A C 3
A B 4
A B 7
A C 8
A B 9

用这样一个最小的例子很难说,但这可能是你想要的:

$ 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
$cat tst.awk
FNR==1{

对于(i=1;i很难用这样一个最小的例子来说明,但这可能是您想要的:

$ 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
$cat tst.awk
FNR==1{

对于(i=1;ii如果在
ab
列中包含
12
的100行数据中有10行,您希望如何打印结果?假设在
ac
列中包含
12
的100行数据中也有15行;您希望如何打印结果。为什么有两列名称相同,a?这些列是否始终包含彼此相同的数据?我们将“B”或“C”与哪个“A”进行比较是否重要?如果是,脚本如何知道您希望使用哪个?它不知道为什么有两个?埃德蒙顿,哪个“A”无关紧要因为它们在每次比较中都是相同的。@JonathanLeffler,理想情况下,我希望样本ID后跟发现12的行连接在一起。如果在
AB
列中有100行包含
12
,那么您希望如何打印结果?假设还有15行在
a C
列中包含
12
的一百个列中,您希望如何打印结果。为什么有两列名称相同,a?这些列是否始终包含彼此相同的数据?我们比较“B”或“C”的“a”是否重要反对?如果是的话,脚本怎么知道你想要它使用哪一个?它不知道为什么有两个?@EdMorton,哪一个“a”无关紧要因为它们在每次比较中都是相同的。@JonathanLeffler,理想情况下,我希望示例ID后面的行与发现的1 2连接在一起。非常感谢!您能解释一下
awk
脚本的第一部分吗?我不太懂
let[I]=$i
let
是一个数组,包含文件第一行中的字母。它与某些语言中用于引入赋值的关键字let无关。将
let
更改为
name
以消除这种混淆。非常感谢!请解释
awk
脚本的第一部分好吗?i不太理解
let[i]=$i
let
是一个数组,包含文件第一行中的字母。它与某些语言中用于引入赋值的关键字let无关。将
let
更改为
name
,以消除这种混淆。