Bash awk:如何从文件A中提取文件B中指定索引的列?

Bash awk:如何从文件A中提取文件B中指定索引的列?,bash,unix,awk,Bash,Unix,Awk,我的文件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

我的文件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中提取“key”条目,如何将这些值导入文件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命令的特定示例。

文件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   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
文件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,,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列):


如果要从文件B(键
列,而不是
pos
)读取列索引并从文件A打印这些列,还可以保持文件B中列索引的顺序,可以尝试:

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
awk'NR==FNR{c[NR]=$(NF-2);n=NR;next}
{printf“%s%s”,$1,$2;

对于(i=2;iOk),这里有一个更新的版本,它应该会重现您的输出

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 
awk'argid==2&&!/SNP/{cols[++i]=$9}argid==4{printf(“%s%s”,$1,$2);

对于(j=1;j替代方法:在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-F,'NR>1{a=a“,$”$9}END{print{print$1,$2“a}}}'cols.awk
awk-f cols.awk文件a
或作为一行,无中间文件:

#!/bin/bash
awk "$(awk -F, 'NR>1{a=a",$"$9}END{print"{print $1,$2"a"}"}' < fileB)" fileA
!/bin/bash
awk“$(awk-F,'NR>1{a=a”,$”$9}END{print“{print$1,$2“a}}}”
为什么
$803428、$803442、$803442
为什么
803456
被忽略?而且,文件B中的
pos
列实际上是
2964936529649737….
,你的意思是
列?请根据
fileA
fileB
的示例输入向我们展示你所需的输出。祝你好运。@Kent-你呢关于pos/key错误,您是对的-我正在更改此项。仅出于示例目的,803456被忽略。您好,Kent,该命令未按预期工作-我将awk命令的输出放在问题的末尾。@Alexandra如果您将第3行更改为
,是否有帮助(i=1;通过此修改,我得到的输出与以前相同。@Alexandra我知道,在您的文件B中,有一个标题行,这一行应该被忽略。请尝试更新的答案,它应该适合您。输出与文件a相同,第5列和第7列未被删除。您好,amaurea,该命令未按预期工作-我从您的awk中输入了输出命令。@Alexandra:请编辑您的问题以包含所需的输出,因为您包含了两个示例文件。否则,您会让人们花时间猜测您需要什么。此外,这类问题(使用不同的术语)每周出现2-3次。你在上课吗?这是作业吗?祝你好运。@Sheller-这是与工作相关的。如果你能找到解决所描述问题的具体问题,请随意参考。@Alexandra:我已经用一个新版本更新了我的答案,它再现了你的输出。我以前误解了你想要什么d去做,并且认为A中的每一行在B中有一行,并且每行只提取一列。新版本从B中收集列号,然后从A的每一行提取所有列。
#!/bin/bash
awk "$(awk -F, 'NR>1{a=a",$"$9}END{print"{print $1,$2"a"}"}' < fileB)" fileA