根据第二个文件中相应的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
是两者的关键,因此我们可以匹配4
和ID001
,依此类推其他键。
在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列表从文件中提取第一个条目?的主要内容,如果未能解决你的问题,请参考以下文章