在两列中使用特定值替换awk

在两列中使用特定值替换awk,awk,Awk,我有一个文件如下所示: 20:60479_C_T 60479 C T 0 0 0 0 0 1 0 1 20:60522_T_TC 60522 T TC 0 0 0 0 0 0 0 20:60568_A_C 60568 A C 0 0 1 0 0 1 20:60571_C_A 60571 C A 0 1 0 1 0 0 20:60579_G_A 60579 G A 0 0 1 0 0 0 我当前的文件更大,有300万行和3000列。我想使用列$3和$4中的值替换其余

我有一个文件如下所示:

20:60479_C_T 60479 C T  0 0 0 0 0 1 0 1
20:60522_T_TC 60522 T TC        0 0 0 0 0 0 0 
20:60568_A_C 60568 A C  0 0 1 0 0 1 
20:60571_C_A 60571 C A  0 1 0 1 0 0 
20:60579_G_A 60579 G A  0 0 1 0 0 0 
我当前的文件更大,有300万行和3000列。我想使用列
$3
$4
中的值替换其余列中的
0
1
。所需的输出将是:

20:60479_C_T 60479 C T  C C C C C T C T
20:60522_T_TC 60522 T TC        T T T T T T T 
20:60568_A_C 60568 A C  A A C A A C 
20:60571_C_A 60571 C A  C A C A C C 
20:60579_G_A 60579 G A  G G A G G G 
我知道如何在几个专栏中这样做:

awk '{d["0"]=$3; d["1"]=$4; print "20", $1, "0", $2, d[$5], d[$6];}' myfile

但是我不知道如何自动为所有列执行此操作,并且避免使用
gsub
中的
awk
手动添加所有列:

$ awk '{d[1]=$1;d[2]=$2;gsub(/0/,$3);gsub(/1/,$4);$1=d[1];$2=d[2];}1' myfile
20:60479_C_T 60479 C T C C C C C T C T
20:60522_T_TC 60522 T TC T T T T T T T
20:60568_A_C 60568 A C A A C A A C
20:60571_C_A 60571 C A C A C A C C
20:60579_G_A 60579 G A G G A G G G

由于列的数量可变,您可能可以通过以下方式逃脱:

awk <testprog.in '{for (i = 5; i <= NF; i++){$i = $($i+3)}print}'
当然,您需要使用更大的数据集来检查它的性能。在我的盒子里,一个300万行的文件,每个文件有3000个条目,大约需要半个小时

与C程序比较(尽管公认为‘脏’,与你的特定输入数据有很大关系,没有我通常认为必要的错误检查),只需要大约十分钟。


为了完整起见,这里有一个C变体,假设它被称为
prog.C
,您可以使用
gcc-o prog.C
之类的东西进行编译,并使用
/prog
$awk'{d[0]=$3;d[1]=$4;对于(i=5;iApologies,Gioconda),我错误地认为您后面的行有太多的列(由于
$3
$4
而计算错误)然后,当我发现我的错误时,我的下一票被锁定了。所以,如果你想知道为什么我做了一个看似不相关的编辑,那就是为了让我可以逆转我说的下一票。再次道歉,我只是想我最好解释一下。考虑到OPs的样本数据,并假设她所有的其他数据都是相似的,这可能没什么问题,但如果3美元或4美元的下一票我有一个符号(
&
)非常感谢@paxdiablo,我是C语言的新手,我需要编译这个程序吗?如果我的文件名为
file.txt
,你能在答案中添加一行关于如何运行它的内容吗?谢谢你的解释explanation@user2380782,在C代码部分之前添加了关于如何执行此操作的注释。
20:60479_C_T 60479 C T C C C C C T C T
20:60522_T_TC 60522 T TC T T T T T T T
20:60568_A_C 60568 A C A A C A A C
20:60571_C_A 60571 C A C A C A C C
20:60579_G_A 60579 G A G G A G G G
#include <stdio.h>
#include <ctype.h>

static char buff[102040];

static char *getStr(char *buff, int *pSz) {
    if (*buff == 0) return NULL;

    char *nextBuff = buff;
    while ((nextBuff[0] != 0) && isspace(nextBuff[0])) {
        nextBuff++;
    }
    if (*nextBuff == 0) return NULL;

    *pSz = 0;
    while ((nextBuff[*pSz] != 0) && ! isspace(nextBuff[*pSz])) {
        (*pSz)++;
    }

    return nextBuff;
}

int main(void) {
    char *str, *str3, *str4; int sz, sz3, sz4;

    while (fgets(buff, sizeof(buff), stdin) != NULL) {
        str = getStr(buff, &sz); printf("%*.*s", sz, sz, str);
        str = getStr(str + sz, &sz); printf(" %*.*s", sz, sz, str);
        str3 = getStr(str + sz, &sz3); printf(" %*.*s", sz3, sz3, str3); 
        str4 = getStr(str3 + sz3, &sz4); printf(" %*.*s", sz4, sz4, str4);

        str = getStr(str4 + sz4, &sz);
        while (str != NULL) {
            if (*str == '0') {
                printf(" %*.*s", sz3, sz3, str3);
            } else {
                printf(" %*.*s", sz4, sz4, str4);
            }
            str = getStr(str + sz, &sz);
        }
        printf("\n");
    }
    return 0;
}
$ awk '{d[0]=$3; d[1]=$4; for (i=5; i<=NF; i++) $i=d[$i]} 1' file
20:60479_C_T 60479 C T C C C C C T C T
20:60522_T_TC 60522 T TC T T T T T T T
20:60568_A_C 60568 A C A A C A A C
20:60571_C_A 60571 C A C A C A C C
20:60579_G_A 60579 G A G G A G G G