我有多个文件SRR3384742.Gene.out.tab
SRR3384743.Gene.out.tab
SRR3384744.Gene.out.tab
,按这个顺序还有更多。我正在从这些文件中提取第一列和第四列并将其存储在输出文件中。我试图确保当我的脚本读取一个新文件时,它应该以制表符分隔的方式提取数据,而不是在每个文件的末尾附加数据。
输入文件:
SRR3384742.Gene.out.tab
N_unmapped 313860 313860 313860
N_multimapping 5786679 5786679 5786679
N_noFeature 286816 31696770 438410
N_ambiguous 1283487 32117 65902
AT1G01010 301 0 301
AT1G01020 623 1 622
AT1G03987 5 5 0
AT1G01030 151 2 149
SRR3384743.Gene.out.tab
N_unmapped 780346 780346 780346
N_multimapping 4621162 4621162 4621162
N_noFeature 182428 28470016 362650
N_ambiguous 1451612 43059 117293
AT1G01010 154 3 151
AT1G01020 685 2 683
AT1G03987 0 0 0
AT1G01030 63 0 63
我得到的输出:
SRR3384742.Gene.out.tab
AT1G01010 301
AT1G01020 622
AT1G03987 0
AT1G01030 149
SRR3384743.Gene.out.tab
AT1G01010 151
AT1G01020 683
AT1G03987 0
AT1G01030 63
所需的输出:
SRR3384742.Gene.out.tab SRR3384743.Gene.out.tab
AT1G01010 301 151
AT1G01020 622 683
AT1G03987 0 0
AT1G01030 149 63
我尝试了以下脚本:
for sample in *Gene.out.tab; do echo -en $sample "\n"; awk 'NR>4 {print $1 "\t" $4}' $sample; awk '{print $0, $sample}' OFS='\t' $sample; done > output
这应该使用 GNU 为您提供注释中描述的输出
awk
:而且,为了让它们在视觉上也很好地对齐,请通过
column
:FNR
是一个特殊的 awk 变量,它始终保存正在处理的当前文件的行号。FILENAME
是一个 GNUawk
特殊变量,它保存当前正在处理的文件的名称。FNR==1{names[c++]=FILENAME}
: 如果这是其中一个输入文件的第一行,则使用该变量c
作为names
其值为文件名的数组的索引,并将其值递增 yb 1 (c++
)。处理完所有文件后,files[0]
将是第一个文件名,files[1]
将是第二个,依此类推。FNR>4{ lines[$1] = "x"lines[$1] ? lines[$1]"\t"$4 : $4; }
:这相当于:如果当前输入文件的行号为 5 或更多,请检查第一个字段是否在数组中具有关联值
lines
。我们检查使用"x"lines[$i]
,因为如果lines[$1]
是0
,那么测试将是假的,但x0
它是真的,所以x
可以防止这种情况。因此,如果我们确实有一个值,我们将一个制表符和当前行的第二个字段附加到它,如果我们没有一个值,我们将它设置为当前行的第四个字段。END{ ... }
:在处理完所有输入后执行此操作。for(i=0;i<=c;i++){printf "\t%s",names[i]}; printf "\n";
:打印数组中的每个文件名names
,前面有一个制表符。我们希望前导选项卡确保我们在标题行和内容中具有相同数量的字段。打印文件名后,打印一个换行符。for(i in lines){print i,lines[i]}
:对于lines
数组的每个索引,打印索引(ID),然后打印在第一步中存储的相关值。限制:这需要将所有输出数据存储在内存中。这在现代机器上真的不应该是一个问题,因为我们只存储 ID 并且每个文件每个 ID 只存储一个值,因此它应该能够在相当不错的机器上阻塞之前处理大量输入,但它可能会成为一个大量数据的问题。
利用
join
利用
paste
我认为
paste
这是您正在寻找的:此解决方案假定所有人
*.tab
都应具有:这是一个打印标题并处理多个文件的脚本:
输出