我有三个文件,我想从中提取一些列并将它们粘贴到一个新文件中。文件不一定具有相同的行数。它们按第一列中的值排序。
文件1具有以下结构:
col1;col2;col3;col4
SAMPLE-1;1;1;1
SAMPLE-2;1;1;1
SAMPLE-3;1;1;1
SAMPLE-4;1;1;1
此文件由“;”分隔而不是“,”
文件2具有以下结构:
col5,col6,col7,col8
SAMPLE-1_OTHER_INFO,2,2,2
SAMPLE-2_OTHER_INFO,2,2,2
SAMPLE-3_OTHER_INFO,2,2,2
文件3具有以下结构:
col9,col10,col11,col12
SAMPLE-1_OTHER_INFO,3,3,3
SAMPLE-2_OTHER_INFO,3,3,3
SAMPLE-3_OTHER_INFO,3,3,3
输出文件(summary.csv)应如下所示:
col1,col2,col4,col6,col7,col10,col12
SAMPLE-1,1,1,2,2,3,3
SAMPLE-2,1,1,2,2,3,3
SAMPLE-3,1,1,2,2,3,3
SAMPLE-4,1,1,,,,
基本上,所有三个文件的第一列都包含样本标识符。 file1的'col1'应该是输出文件的第一列。然后,col1中的标识符应与file2和file3的col5和col9中的标识符匹配。进行比较时不应考虑'_OTHER_INFO'部分。
如果匹配,则应添加文件2和3的col6,col7,col10和col12值的信息。
如果没有匹配,该行仍应在输出文件中,但最后四列应为空(如本例'SAMPLE-4')
我打算用awk或'cut / paste'命令执行此操作。但是我不知道如何在col1,col5和col9中查找值之间的匹配。
答案 0 :(得分:2)
尝试关注并告诉我这是否对您有所帮助。
awk 'BEGIN{
FS=";"
}
FNR==1{
f++
}
f==1 && FNR>1{
a[$1]=$2","$4;
next
}
f>1 && FNR==1 {
FS=","
}
f==2 && FNR>1{
sub(/_.*/,"",$1);
b[$1]=$2","$3;
next
}
f==3 && FNR>1{
sub(/_.*/,"",$1);
c[$1]=$2","$4;
next
}
END{
print "col1,col2,col4,col6,col7,col10,col12";
for(i in a){
printf("%s,%s,%s,%s\n",i,a[i],b[i]?b[i]:",",c[i]?c[i]:",")
}
}
' file1 file2 file3
有时会尝试添加解释。
EDIT1: 也添加了单线形式的解决方案。
awk 'BEGIN{FS=";"}FNR==1{f++} f==1 && FNR>1{;a[$1]=$2","$4;next} f>1 && FNR==1{FS=","} f==2&&FNR>1{sub(/_.*/,"",$1);b[$1]=$2","$3;next} f==3&&FNR>1{sub(/_.*/,"",$1);c[$1]=$2","$4;next} END{print "col1,col2,col4,col6,col7,col10,col12";for(i in a){printf("%s,%s,%s,%s\n",i,a[i],b[i]?b[i]:",",c[i]?c[i]:",")}}' file1 file2 file3
答案 1 :(得分:0)
排序 + sed 技巧(对于已排序的输入文件):
join -t, -j1 -a1 -o1.1,1.2,1.4,2.2,2.3 <(tr ';' ',' < file1) <(sed 's/_[^,]*//g' file2)
| join -t, - -a1 -o1.1,1.2,1.3,1.4,1.5,2.2,2.4 <(sed 's/_[^,]*//g' file3)
输出:
SAMPLE-1,1,1,2,2,3,3
SAMPLE-2,1,1,2,2,3,3
SAMPLE-3,1,1,2,2,3,3
SAMPLE-4,1,1,,,,