我的文件A 的格式如下,包含数十万列和数千行:
1000->100001 DOSE 2.000 2.000 2.000 2.000 2.000 ....
1001->100101 DOSE 1.988 1.988 2.000 2.000 2.000 ....
1001->100101 DOSE 1.933 2.000 2.000 2.000 2.000 ....
1002->100201 DOSE 2.000 2.000 2.000 2.000 2.000 ....
1002->100201 DOSE 2.000 2.000 2.000 2.000 2.000 ....
虽然我的文件B (数千个条目)具有以下格式:
SNP,Al1,Al2,Freq1,MAF,AvgCall,Rsq,Genotyped,key,pos,gene_key
20:29649365,C,T,0.93021,0.06979,0.93021,0.10115,,803428,29649365,12
20:29649737,A,G,0.93914,0.06086,0.93914,0.14303,,803442,29649737,12
20:29649765,T,G,0.99963,0.00037,0.99963,0.13918,,803443,29649765,12
20:29650462,A,T,0.89387,0.10613,0.89388,0.12864,,803456,29650462,12
我想要做的是从文件A中提取前两列以及文件B中“key”列中指定的列。我花了一些时间试图弄清楚如何使用awk这样做,但它一直在服用对理论上不应该太困难的事情来说太长了。
我的具体问题是:一旦我从文件B中提取“密钥”条目,我如何将这些值传递给文件A的awk命令?
文件B中前3列的手动命令:
awk '{print $1, $2, $803428, $803442, $803442}' fileA > output.txt
编辑:
文件A 和文件B 之间没有公共列。 文件A 中第803428列中的值表示来自文件B 的SNP“20:29649365”的结果。
如果要运行的命令是:
awk '{print $1, $2, $3, $4, $5}' fileA
结果将是:
1000->100001 DOSE 2.000 2.000 2.000 2.000 2.000
1001->100101 DOSE 1.988 1.988 2.000 2.000 2.000
1002->100201 DOSE 1.933 1.999 2.000 2.000 2.000
1003->100301 DOSE 2.000 2.000 2.000 2.000 2.000
1004->100401 DOSE 2.000 2.000 2.000 2.000 2.000
我用来测试作为解决方案提供的awk命令的具体示例。
的fileA:
1000->100001 DOSE 2.000 2.000 2.000 2.000 2.000
1001->100101 DOSE 1.988 1.988 2.000 2.000 2.000
1001->100101 DOSE 1.933 2.000 1.500 2.000 2.000
1002->100201 DOSE 2.000 2.000 2.000 2.000 1.622
1002->100201 DOSE 2.000 2.000 2.000 2.000 2.000
FILEB:
SNP,Al1,Al2,Freq1,MAF,AvgCall,Rsq,Genotyped,key,pos,gene_key
20:29649365,C,T,0.93021,0.06979,0.93021,0.10115,,3,29649365,12
20:29649737,A,G,0.93914,0.06086,0.93914,0.14303,,4,29649737,12
20:29650462,A,T,0.89387,0.10613,0.89388,0.12864,,6,29650462,12
所需的输出(第1,2,3,4,6列 - 来自fileB的键列的最后3列):
1000->100001 DOSE 2.000 2.000 2.000
1001->100101 DOSE 1.988 1.988 2.000
1001->100101 DOSE 1.933 2.000 2.000
1002->100201 DOSE 2.000 2.000 2.000
1002->100201 DOSE 2.000 2.000 2.000
答案 0 :(得分:3)
如果你想从fileB(key
列,而不是pos
)读取列索引并从fileA打印那些列,也保持col索引在fileB中的顺序,你可以尝试:
awk 'NR==FNR{c[NR]=$(NF-2);n=NR;next}
{printf "%s %s",$1,$2;
for(i=2;i<=n;i++)printf " %s",$c[i];print ""}' FS=',' fileB FS=' ' fileA
答案 1 :(得分:3)
好的,这是一个应该重现输出的更新版本。
awk 'ARGIND==2&&!/SNP/{cols[++i]=$9}ARGIND==4{printf("%s %s",$1,$2);
for(j=1;j<=i;j++)printf(" %s%s",$cols[j],j<i?"":"\n");}' FS=',' B.txt FS='[ \t]+' A.txt
两个文件中的不同字段分隔符和B文件中的标题必须被忽略,这有点复杂。但关键是$
接受一个变量,而不仅仅是一个常数整数。此方法将列列表存储在cols
数组中,并针对A中的每一行迭代它们。
在文件之间切换字段分隔符是通过虚拟文件FS=','
和&#39; FS =&#39; [\ t] +&#39;`来完成的,这意味着我们的实际文件已经过了2和4.
答案 2 :(得分:1)
替代方法:在fileB上应用awk脚本生成另一个awk脚本,以应用于fileA。
#!/bin/bash
awk -F, 'NR>1{a=a",$"$9}END{print"{print $1,$2"a"}"}' < fileB > cols.awk
awk -f cols.awk fileA
或者作为单行,没有中间文件:
#!/bin/bash
awk "$(awk -F, 'NR>1{a=a",$"$9}END{print"{print $1,$2"a"}"}' < fileB)" fileA