由两列的合并文件 [英] combine files consisting of two columns
问题描述
我有一个看起来像这样多个文件:
文件1:
rsRNA-2312-N 2
rsRNA-6508-N 2
rsRNA-6382-N 10
rsRNA-951-N 0
rsRNA-6330-N 4
rsRNA-6330-N 11
rsRNA-1385-N 3
rsRNA-4945-N 0
rsRNA-946-N 9
文件2:
rsRNA-552-N 2
rsRNA-5301-N 7
rsRNA-6487-N 0
rsRNA-4945-N 7
rsRNA-2445-N 9
rsRNA-6490-N 2
file3的:
rsRNA-4946-N 1
rsRNA-5058-N 0
rsRNA-552-N 0
rsRNA-849-N 2
rsRNA-3302-N 2
rsRNA-4099-N 0
rsRNA-552-N 1
我想合并创建具有的值在一个单独的列和列1的唯一标识符(在输入文件中第1列)的每个输入文件一个输出文件。如果在一个特定的输入的文件没有找到标识符,计数应为此标识符此特定输入是0。
样输出(不是真正的数据):
标识符文件1文件2文件3
rsRNA-552-N 2 4 5
rsRNA-5301-N 7 12 2
rsRNA-6487-N 0 1 5
rsRNA-4945-N 7月12日1
rsRNA-2445-N 9 4 55
rsRNA-6490-N 2 1 0
试图:
粘贴≤(AWK'{打印$ 2}'文件1)≤(AWK'{打印$ 2}'文件2)≤(AWK'{打印$ 2}'文件3)LT (AWK'{打印$ 2}'file4将)
和使用for循环:
在文件f *;做
BASE_NAME = $ {F%的.txt}
ID = $ {#BASE_NAME * _}
AWK> 输出$ {ID}
DONE
使用一个shell循环处理文本永远是错误的做法。只要使用awk中,它的目的是要去做。使用GNU AWK中4 *为真正的多-D阵列和ARGIND和分类
:
$猫tst.awk
{
拆分($ 1,,/ - /)
键= A [2]
key2name [关键] = $ 1
key2val [关键] [ARGIND] = $ 16
}
结束 {
printf的标识符
为(fileNr = 1; fileNr&下; = ARGIND; fileNr ++){
printf的%s%S,OFS,ARGV [fileNr]
}
打印 PROCINFO [sorted_in] =@ind_num_asc
对(在key2name键){
printf的%S,key2name [关键]
为(fileNr = 1; fileNr&下; = ARGIND; fileNr ++){
printf的%s%S,OFS(fileNr在key2val [关键] key2val [关键] [fileNr]:0)
}
打印
}
}
$ AWK -f tst.awk文件1文件2文件3
标识符文件1文件2文件3
rsRNA-552-N 0 2 1
rsRNA-849-N 0 0 2
rsRNA-946-N 9 0 0
rsRNA-951-N 0 0 0
rsRNA-1385-N 3 0 0
rsRNA-2312-N 2 0 0
rsRNA-2445-N 0 9 0
rsRNA-3302-N 0 0 2
rsRNA-4099-N 0 0 0
rsRNA-4945-N 0 7 0
rsRNA-4946-N 0 0 1
rsRNA-5058-N 0 0 0
rsRNA-5301-N 0 7 0
rsRNA-6330-N 11 0 0
rsRNA-6382-N 10 0 0
rsRNA-6487-N 0 0 0
rsRNA-6490-N 0 2 0
rsRNA-6508-N 2 0 0
我添加了键的略微增加的复杂性
作为第一个字段的数字部分,以便输出,他们可以用数字上的子场排序的结果时。
I have multiple files that look like this:
file1:
rsRNA-2312-n 2
rsRNA-6508-n 2
rsRNA-6382-n 10
rsRNA-951-n 0
rsRNA-6330-n 4
rsRNA-6330-n 11
rsRNA-1385-n 3
rsRNA-4945-n 0
rsRNA-946-n 9
file2:
rsRNA-552-n 2
rsRNA-5301-n 7
rsRNA-6487-n 0
rsRNA-4945-n 7
rsRNA-2445-n 9
rsRNA-6490-n 2
file3:
rsRNA-4946-n 1
rsRNA-5058-n 0
rsRNA-552-n 0
rsRNA-849-n 2
rsRNA-3302-n 2
rsRNA-4099-n 0
rsRNA-552-n 1
I would like to merge the files creating a output that has the values for each input file in a separate column and unique identifier (column 1 in the input file) in column1. If an identifier is not found in a specific input file, the count should be 0 for this identifier for this specific input.
output like (not real data):
identifier file1 file2 file3
rsRNA-552-n 2 4 5
rsRNA-5301-n 7 12 2
rsRNA-6487-n 0 1 5
rsRNA-4945-n 7 12 1
rsRNA-2445-n 9 4 55
rsRNA-6490-n 2 1 0
Was trying:
paste <(awk '{print $2}' file1 ) <(awk '{print $2}' file2 ) <(awk '{print $2}' file3) <(awk '{print $2}' file4)
and using a for loop:
for f in file*; do
base_name=${f%.txt}
id=${base_name#*_}
awk > "output${id}"
done
Using a shell loop to manipulate text is always the wrong approach. Just use awk, it's what it was designed to do. Using GNU awk 4.* for true multi-D arrays and ARGIND and sorted in
:
$ cat tst.awk
{
split($1,a,/-/)
key = a[2]
key2name[key] = $1
key2val[key][ARGIND] = $2
}
END {
printf "identifier"
for (fileNr=1;fileNr<=ARGIND;fileNr++) {
printf "%s%s", OFS, ARGV[fileNr]
}
print ""
PROCINFO["sorted_in"] = "@ind_num_asc"
for (key in key2name) {
printf "%s", key2name[key]
for (fileNr=1;fileNr<=ARGIND;fileNr++) {
printf "%s%s", OFS, (fileNr in key2val[key] ? key2val[key][fileNr] : 0)
}
print ""
}
}
.
$ awk -f tst.awk file1 file2 file3
identifier file1 file2 file3
rsRNA-552-n 0 2 1
rsRNA-849-n 0 0 2
rsRNA-946-n 9 0 0
rsRNA-951-n 0 0 0
rsRNA-1385-n 3 0 0
rsRNA-2312-n 2 0 0
rsRNA-2445-n 0 9 0
rsRNA-3302-n 0 0 2
rsRNA-4099-n 0 0 0
rsRNA-4945-n 0 7 0
rsRNA-4946-n 0 0 1
rsRNA-5058-n 0 0 0
rsRNA-5301-n 0 7 0
rsRNA-6330-n 11 0 0
rsRNA-6382-n 10 0 0
rsRNA-6487-n 0 0 0
rsRNA-6490-n 0 2 0
rsRNA-6508-n 2 0 0
I added the slight additional complexity of the key
as the numeric part of the first field so when outputting the results they can be sorted numerically on that sub-field.
这篇关于由两列的合并文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!