根据第二个文件中相应的ID列表从文件中提取第一个条目?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了根据第二个文件中相应的ID列表从文件中提取第一个条目?相关的知识,希望对你有一定的参考价值。

我有一个2文本文件。 file1包含ID:

0   ABCD  
3   ABDF
4   ACGFR
6   ABCD
7   GFHTRSFS

和file2:

ID001  AB  ACGFR  DF  FD  GF  TYFJ  ANH  
ID002  DFR  AG  ABDF  HGT  MNJ  POI  YUI
ID003  DGT  JHY  ABCD  YTRE  NHYT  PPOOI  IUYNB
ID004  GFHTRSFS  MJU  UHY  IUJ  POL  KUH  KOOL

如果文件1的第二列与文件2中的任何条目匹配,则文件2的第一列应该是它的答案。

输出应该是:

0   ID003
3   ID002
4   ID001
6   ID003
7   ID004

(file1(ABCD)的第2列找到与ID003的文件2的第3行匹配。因此,ID003应该是它的答案)。

我也尝试过其他帖子的例子,但不知怎的,它们与此不匹配。

任何帮助将不胜感激。

亲切的问候

答案

当试图将一个文件中的记录与另一个文件中的记录进行匹配时,想法是使用hash ( also known as an associative array, set of key-value pairs, or dictionaries )来存储第一列和其余列之间的关系。实际上,创建以下关系:

file1: ABCD     -> 0
       ABDF     -> 3
       ACGFR    -> 4
       FGHTRSS  -> 6
       GFHTRSFS -> 7

file2: AB    -> ID001
       ACGFR -> ID001
       DF    -> ID001
       ...
       ANH   -> ID001
       DFR   -> ID002
       AG    -> ID002
       ...
       KUH   -> ID004
       KOOL  -> ID004

文件之间记录的实际匹配等于确定是否两个哈希,这里file1和file2都具有为每个file1记录定义的密钥。在这里我们可以看到ACGFR是两者的关键,因此我们可以匹配4ID001,依此类推其他键。

在perl中,我们可以通过分配值对来创建哈希:

my %hash = ( foo => 1, bar => 2 );

也可以使用引用创建哈希:

my $hash_ref = { foo => 1, bar => 2 };

可以使用keys函数找到键,并可以提取单个值:

my $val1 = $hash{ foo };       # regular hash
my $val2 = $hash_ref->{ foo }; # hash reference

可以使用exists函数测试特定键是否是散列的成员。

有了这个背景,这里有一种方法可以在perl中执行此操作:

matchup_files.评论

#!/usr/bin/env perl

use warnings;
use strict;

my $usage = "usage: $0 file1 file2
";

my ($file1, $file2) = @ARGV;
for my $file ($file1, $file2) {
    die $usage unless defined $file && -f $file; # -f checks whether $file is an actual file
}

# Create mappings col2 -> col1
#                 col3 -> col1
#                 col4 -> col1
my $h1 = inverted_hash_file_on_first_column( $file1 );
my $h2 = hash_file_on_first_column( $file2 );

# Try to find matching pairs
my $matches = {};
for my $h1_key ( keys %$h1 ) {
    my $h1_val = $h1->{$h1_key};
    if ( exists $h2->{ $h1_val } ) {
        # We have a match!
        my $num = $h1_key;
        my $id  = $h2->{ $h1_val };
        $matches->{ $num } = $id;
    }
}

# Print them out in numerical order
for my $num ( sort { $a <=> $b } keys %$matches ) {
    my $id = $matches->{$num};
    print join("  ", $num, $id) . "
";
}

exit 0; # Success

sub inverted_hash_file_on_first_column {
    my ($file) = @_;
    return _hash_file($file, 1);
}

sub hash_file_on_first_column {
    my ($file) = @_;
    return _hash_file($file, 0);
}

sub _hash_file {
    my ($file, $inverted) = @_;

    my $fhash = {};
    open my $fh, "<", $file or die "Unable to open $file : $!";
    while ( my $line = <$fh> ) {
        my @fields = split /s+/, $line; # Split line on whitespace
        my $key = shift @fields; # First column
        for my $field ( @fields ) {
            if ( $inverted ) {
                die "Duplicated field '$field'" if exists $fhash->{ $key };                
                $fhash->{ $key } = $field;
            } else {
                die "Duplicated field '$field'" if exists $fhash->{ $field };
                $fhash->{ $field } = $key;
            }
        }
    }
    return $fhash;
}

产量

matchup_files.pl input1 input2
0  ID003
3  ID002
4  ID001
6  ID003
7  ID004

以上是关于根据第二个文件中相应的ID列表从文件中提取第一个条目?的主要内容,如果未能解决你的问题,请参考以下文章

根据第一个下拉选择填充第二个下拉列表

从文本文件中提取一行中的第二个单词

使用 Java Stream 根据第二个列表中的值过滤列表

Java中的大数据处理

从下拉列表中选择值,第二个下拉列表自动更改

如何加入/子查询第二个表