如何基于多列中的数据合并两个文件?

时间:2020-04-10 15:58:01

标签: if-statement awk multiple-columns

我有两个单独的文件,每个文件包含不同数量的列,我想根据多个列中的数据进行合并。

file1

VMNF01000015.1  1769465 1769675 .   .   -   Focub_II5_mimp_1
VMNF01000014.1  3225875 3226081 .   .   +   Focub_II5_mimp_1
VMNF01000014.1  3226046 3226081 .   .   -   Focub_II5_mimp_1
VMNF01000014.1  3585246 3585281 .   .   -   Focub_II5_mimp_1
VMNF01000014.1  3692468 3692503 .   .   -   Focub_II5_mimp_1
VMNF01000014.1  3715380 3715415 .   .   +   Focub_II5_mimp_1
VMNF01000014.1  2872478 2872511 .   .   -   Focub_II5_mimp_1

file2

VMNF01000014.1  3225875-3226081(+)  gtacttcagcctggattcaaacttattgcatcccactgta
VMNF01000014.1  3226046-3226081(-)  tacacacctgcgaatactttttgcatcccactgta
VMNF01000015.1  1769465-1769675(-)  gtacttcagcctggattcaaacttattgcatcccactgta
VMNF01000014.1  3692468-3692503(-)  tacagtgggatgcaaaaagtattcgcaggtgt
VMNF01000014.1  3715380-3715415(+)  gtacttcagcctggattcaaacttattgcatcccactgta
VMNF01000014.1  3585246-3585281(-)  tacagtgggatgcaaaaagtattcgcaggtgt
VMNF01000014.1  2872478-2872511(-)  gtacttcagcctggattcaaacttattgcatcccactgta

首先,我想我需要在file2中创建另外2列,用“-”分隔数字,并为“(*)”创建新列,但是我不知道如何在不替换“((- )”。到目前为止,我一直在使用以下命令:

awk '{gsub("-","\t",$2);print;}'

完成此操作后,我想将file2中的最后一列添加到file1中。我已经可以使用以下命令执行此操作:

awk 'NR==FNR {a[$1]=$3; next} {print $1,$2,$3,$4,$5,$6,$7,a[$1];}' file2 file1 > file3. 

但是,数据不匹配。它是根据第1列中的条目进行匹配的。在许多情况下,第1列中的数据是相同的,因此file3的第8列中的数据仅匹配其中一个条目,而与第2或3列中的数据不匹配在文件1中

文件3:

VMNF01000015.1  1769465 1769675 .   .   -   Focub_II5_mimp_1    gtacttcagcctggattcaaacttattgcatcccactgta
VMNF01000014.1  3225875 3226081 .   .   +   Focub_II5_mimp_1    gtacttcagcctggattcaaacttattgcatcccactgta
VMNF01000014.1  3226046 3226081 .   .   -   Focub_II5_mimp_1    gtacttcagcctggattcaaacttattgcatcccactgta
VMNF01000014.1  3585246 3585281 .   .   -   Focub_II5_mimp_1    gtacttcagcctggattcaaacttattgcatcccactgta
VMNF01000014.1  3692468 3692503 .   .   -   Focub_II5_mimp_1    gtacttcagcctggattcaaacttattgcatcccactgta
VMNF01000014.1  3715380 3715415 .   .   +   Focub_II5_mimp_1    gtacttcagcctggattcaaacttattgcatcccactgta
VMNF01000014.1  2872478 2872511 .   .   -   Focub_II5_mimp_1    gtacttcagcctggattcaaacttattgcatcccactgta

即使我能够分离file2的第2列中的数据,我仍然会遇到相同的问题,因为在某些情况下第2列中的数据是相同的。我需要的是这样写的代码:区分第2列中的数据(见下文);

VMNF01000014.1  3225875    3226081    (+)   gtacttcagcctggattcaaacttattgcatcccactgta

然后:

如果文件1中的$ 1,$ 2,$ 3与文件2中的$ 1,$ 2,$ 3相匹配,则从文件1中打印$ 1,$ 2,$ 3,$ 4,$ 5,$ 6,$ 7,并从文件2中添加$ 5。

我该怎么做?我知道awk可以使用if语句,但是我不知道如何在awk中使用它们。

有什么建议吗?

2 个答案:

答案 0 :(得分:2)

请您尝试以下。

awk '
FNR==NR{
  split($2,array,"[-(]")
  mainarray[$1,array[1],array[2]]=$NF
  next
}
(($1,$2,$3) in mainarray){
  print $0,mainarray[$1,$2,$3]
}
'  Input_file2  Input_file1

第二个解决方案: 由于OP在上述代码中出现错误,因此在上面进行了一些更改。

awk '
FNR==NR{
  split($2,array,"[-(]")
  key=$1 OFS array[1] OFS array[2]
  mainarray[key]=$NF
  next
}
{ key = $1 OFS $2 OFS $3 }
(key in mainarray){
  print $0,mainarray[key]
}
'  Input_file2  Input_file1

说明: :添加了上述代码的详细说明。

awk '                                       ##Starting awk program from here.
FNR==NR{                                    ##Checking condition FNR==NR when  Input_file2 is being read.
  split($2,array,"[-(]")                    ##Splitting 2nd field into an array named array where delimiter is - OR (
  mainarray[$1,array[1],array[2]]=$NF       ##Creating mainarray index of $1,array[1],array[2] and value is current line is last field.
  next                                      ##next will skip all further statements from here.
}
(($1,$2,$3) in mainarray){                  ##Checking condition if $1,$2,$3 of current line is present in mainaarray.
  print $0,mainarray[$1,$2,$3]              ##Printing current line with value of mainarray with index of $1,$2,$3
}
'  Input_file2  Input_file1                 ##Mentioning Input_file names here.

答案 1 :(得分:2)

$ awk '
    { key=$1 OFS $2 OFS $3 }
    NR==FNR { map[key]=$NF; next }
    { print $0, map[key] }
' FS='[[:space:](-]+' file2 FS=' ' file1
VMNF01000015.1  1769465 1769675 .   .   -   Focub_II5_mimp_1 gtacttcagcctggattcaaacttattgcatcccactgta
VMNF01000014.1  3225875 3226081 .   .   +   Focub_II5_mimp_1 gtacttcagcctggattcaaacttattgcatcccactgta
VMNF01000014.1  3226046 3226081 .   .   -   Focub_II5_mimp_1 tacacacctgcgaatactttttgcatcccactgta
VMNF01000014.1  3585246 3585281 .   .   -   Focub_II5_mimp_1 tacagtgggatgcaaaaagtattcgcaggtgt
VMNF01000014.1  3692468 3692503 .   .   -   Focub_II5_mimp_1 tacagtgggatgcaaaaagtattcgcaggtgt
VMNF01000014.1  3715380 3715415 .   .   +   Focub_II5_mimp_1 gtacttcagcctggattcaaacttattgcatcccactgta
VMNF01000014.1  2872478 2872511 .   .   -   Focub_II5_mimp_1 gtacttcagcctggattcaaacttattgcatcccactgta