将多个文件(两个以上)与两个不同的列进行比较

将多个文件(两个以上)与两个不同的列进行比较

我有四个不同的文件:file1、file2、file3、file4。每个文件都有 2 个不同的列,用制表符分隔。我想将 file1 的第一列(作为参考)与第二个文件、第三个和第四个文件的第一列进行匹配,并打印匹配的第一列和每个文件的具有匹配第一列的第二列。文件看起来像:

文件1

Bm1_00085|Bm1_22625    0.263974289
Bm1_00087|Bm1_22620    0.663443490    

文件2

Bm1_00085|Bm1_22625    0
Bm1_57630|Bm1_52870    0

文件3

Bm1_57630|Bm1_54855    0
Bm1_00085|Bm1_22625    4

文件4

Bm1_57630|Bm1_52870    0
Bm1_00085|Bm1_22625    1

输出:

Bm1_00085|Bm1_22625 0.263974289 0 4 1

答案1

有了join一个足够聪明的 shell 知道如何处理<(...)

join <(sort file1) <(sort file2) | join - <(sort file3) | join - <(sort file4)

输出:

Bm1_00085|Bm1_22625 0.263974289 0 4 1

答案2

这是使用 awk 实现的一种方法:

解析.awk

# Use the first column of the first file as a key and the second column
# as a value in the h hash
NR==FNR { h[$1] = $2; next }

# If $1 is a key in h append $2 to h[$1]
$1 in h { h[$1] = h[$1] OFS $2 }

# When the input has been exhausted, print h key value pairs
# that contain more than one element 
END { for(k in h)
  if(split(h[k], a) > 1)
    print k OFS h[k]
}

像这样运行它:

awk -f parse.awk file1 file2 file3 file4

输出:

Bm1_00085|Bm1_22625 0.263974289 0 4 1

答案3

在 Perl 中,完成这项工作的工具是哈希。哈希是一组键值对,这使得这种交叉引用变得非常容易。

注意 - 这将仅有的如果第一个字段是唯一的,则有效:

#!/usr/bin/env perl
use strict;
use warnings;
my %data;

while (<>) {
    my ( $key, $value ) = split;
    push( @{ $data{$key} }, $value );
}

foreach my $key ( sort keys %data ) {
    if ( @{ $data{$key} } >= @ARGV ) {
        print join( "\t", $key, @{ $data{$key} } ), "\n";
    }
}

调用为myscript.pl file1 file2 file3 file4.

它:

  • 通过 读取命令行中的文件列表<>,并打开它们进行处理。
  • 一次迭代一行,将该行拆分为$key$value
  • 存储$value在数组的哈希中。

  • 遍历哈希中的每个键

  • 如果元素数量 >= 命令行参数数量(例如文件数量) - 则打印该行。

输出是:

Bm1_00085|Bm1_22625 0.263974289 0   4   1

笔记:

假定所有文件中都有唯一的“键”。

相关内容