Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在perl中将制表符分隔的文件读入哈希并搜索_Perl_Search_Hash - Fatal编程技术网

在perl中将制表符分隔的文件读入哈希并搜索

在perl中将制表符分隔的文件读入哈希并搜索,perl,search,hash,Perl,Search,Hash,我有一个制表符分隔的文件(inpFile.txt)作为 我想读取它并将其存储到哈希(hashname)中 一旦我的散列准备好了,我想搜索是否找到($key,$value)对。例如,是否找到(eee2,aaa2) 我是Perl的初学者,但我知道用Perl可以有效地完成,而且很容易 我编写了以下代码。你能再延长一点吗 谢谢 #!/usr/local/bin/perl open (LIST1, "/inpFile.txt") || die "File not found\n"; while

我有一个制表符分隔的文件(inpFile.txt)作为

我想读取它并将其存储到哈希(hashname)中

一旦我的散列准备好了,我想搜索是否找到($key,$value)对。例如,是否找到(eee2,aaa2)

我是Perl的初学者,但我知道用Perl可以有效地完成,而且很容易

我编写了以下代码。你能再延长一点吗

谢谢

#!/usr/local/bin/perl

open (LIST1, "/inpFile.txt") || die "File not found\n";
     while (<LIST1>) {
          ($tmpvar1, $tmpvar2) = split(/\t/, $_);
          $hashname{$tmpvar1} = $tmpvar2;
     }
close(LIST1);
#/usr/local/bin/perl
打开(LIST1,“/inpFile.txt”)| | die“未找到文件\n”;
而(){
($tmpvar1,$tmpvar2)=拆分(/\t/,$);
$hashname{$tmpvar1}=$tmpvar2;
}
关闭(列表1);

您的输入文件将只产生三元素哈希,因为键是重复的。在现实生活中,您必须处理这种情况,但在这种情况下,我会更改您的输入文件:

aaa1    aaa2
bbb1    bbb2
ccc1    ccc2
ccc1    ddd2
eee2    aaa2
下面是对代码的一些增强:

#!/usr/local/bin/perl

#always use strict and warnings
use strict;
use warnings;
use Data::Dumper;

hash_test();
#Try to put your code in separate subs if possible 
sub hash_test {
   my %hashname = ();
   read_into_hash( \%hashname );
   print Dumper( \%hashname );    # Test your hash
   search_hash( \%hashname, "eee2", "aaa2" );
}

sub read_into_hash {

   #Always declare variables
   my $list1;
   my $tmpvar1;
   my $tmpvar2;
   my $hash_ref = shift;
   my $lineno = 0;
   open( $list1, "<", "/inpFile.txt" ) or die "File not found\n";
   while (<$list1>) {
       $lineno++;
       chomp;    #delete new line character
       ( $tmpvar1, $tmpvar2 ) = split( /\t/, $_ );
       if (defined $hash_ref->{$tmpvar1})
       {
         # adding lineno from file to avoid overwriting. I use '~' just in case
         # if your keys could include such character, use something else
         $tmpvar1 .= "~" . $lineno;
       }
       $hash_ref->{$tmpvar1} = $tmpvar2;

   }

   close($list1);
}

sub search_hash {
   my $hash_ref = shift;
   my $key      = shift;
   my $value    = shift;

   if (defined $hash_ref->{$key} && $hash_ref->{$key} =~ /^$value(\~\d+)*$/)
   {
           print "Found.\n";
       }
}
#/usr/local/bin/perl
#始终使用严格的警告和警告
严格使用;
使用警告;
使用数据::转储程序;
hash_测试();
#如果可能的话,试着把你的代码放在不同的sub中
子散列检验{
我的%hashname=();
将\u读入\u散列(\%hashname);
打印转储程序(\%hashname);#测试您的哈希
搜索散列(\%hashname,“eee2”,“aaa2”);
}
将\u读入\u散列{
#始终声明变量
我的$list1;
我的$tmpvar1;
我的$tmpvar2;
my$hash_ref=shift;
我的$lineno=0;

打开($list1,“当您遇到Perl时,首先使用pragma
use strict;

我注意到你的文件是由

aaa1  aaa2
aaa1  bbb2
在处理我们的文件期间,散列将只存储一个键
'aaa1'=>'bbb2'
,因为Perl在散列中有唯一的键

use strict;

open my $fh, '<', '/input_file.txt' 
    or die "Cant open file $!";

LINE:
while (my $line = <$fh>) {
    my ($key, $value) = split /\t/, $line;
    next LINE if not $key;

    $hash{$key} = $value;
}

my $search_key   = 'eee2';
my $search_value = 'aaa2';

if ($hash{$search_key} eq $search_value) {

   print "Found key: $search_key and value: $search_value in hash /n";
}

close $fh;
使用严格;

打开我的$fh,“首先,我将你的问题解释为特定于键/值对上的重复。这有点尴尬——正常的问题只是测试键,但我们可以通过将键和值都作为生成新键的函数的输入来做键值

如果你只是使用一个标签删除的CSV,请使用并确保它是正确的,并且涵盖了最复杂的情况!安装时也要非常快

use strict;
use warnings;
use Data::Dumper;
use Text::CSV;
use IO::Handle;

my $csv = Text::CSV->new({sep_char=>"\t"});
my $fh = IO::Handle->new_from_fd( *DATA, 'r' );

while ( not $fh->eof ) {
  my $row = $csv->getline( $fh );
  warn Dumper $row;
}

__DATA__
aa1 aaa2
aaa1  bbb2
aaa1  ccc2 
ccc1  ddd2
eee2  aaa2
理解了这一点后,剩下的练习也很简单。我使用了一个非常简单的算法,将键和值连接在一起,并以此为哈希索引。这消除了巧妙的冲突尝试,但对于您的任务来说可能不是必需的。请随意提问

use feature ':5.10';
use strict;
use warnings;
use Data::Dumper;
use Text::CSV;
use IO::Handle;
use Digest::SHA qw(sha1_hex);

my $csv = Text::CSV->new({sep_char=>"\t"});
my $fh = IO::Handle->new_from_fd( *DATA, 'r' );

my ( %kv, %sha1_kv );
while ( not $fh->eof ) {
  my $row = $csv->getline( $fh );
  my ($k, $v) = @$row;

  my $sha1 = sha1_hex($k) . sha1_hex($v);

  if ( exists $sha1_kv{ $sha1 } ) {
    say "We have a hit (key/value dupe) for $sha1 [key: $k]";
  }
  else {
    $kv{ $k } = $v;
    $sha1_kv{ $sha1 } = $v;
  }

  warn Dumper $row;
}

__DATA__
aa1 aaa2
aa1 aaa2
aaa1  bbb2
aaa1  ccc2 
ccc1  ddd2
eee2  aaa2

由于您的数据包含具有多个值的键,并且假设数据文件中确实存在这种情况,您可以创建数组哈希(HoA),其中键与数组关联:

use Modern::Perl;

my %hashname;

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

my $searchKey = 'aaa1';
my $searchVal = 'ccc2';

if ( defined $hashname{$searchKey}
    and $searchVal ~~ @{ $hashname{$searchKey} } )
{
    say "key: $searchKey with val: $searchVal found.";
}
else {
    say "key: $searchKey with val: $searchVal not found.";
}

__DATA__
aaa1  aaa2
aaa1  bbb2
aaa1  ccc2 
ccc1  ddd2
eee2  aaa2

希望这有帮助!

事实上,我的数据具有与我所提到的相同的形式。这是否可能对同一个键具有不同的值。或者是否有其他方法可以有效地做到这一点。我的文件超过gigs。然后,您必须添加另一个级别的散列或为相同的键添加前缀/后缀。我的数据具有一个键作为与多个值关联。此代码是否可以处理这种情况?在我的示例中,aaa1与aaa2、bbb2和ccc2 all关联。这是否可能对同一个密钥具有不同的值。或者是否有其他方法可以有效地执行此操作。我的文件超过Gig。更改代码以处理密钥复制问题。搜索子项is也发生了变化。另外请注意,我被用来测试哈希元素的原因是
打印转储程序($hashname)
。如果你处理这么大的文件,请去掉它。谢谢,你问题中的代码片段实际上是我的解决方案!
use Modern::Perl;

my %hashname;

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

my $searchKey = 'aaa1';
my $searchVal = 'ccc2';

if ( defined $hashname{$searchKey}
    and $searchVal ~~ @{ $hashname{$searchKey} } )
{
    say "key: $searchKey with val: $searchVal found.";
}
else {
    say "key: $searchKey with val: $searchVal not found.";
}

__DATA__
aaa1  aaa2
aaa1  bbb2
aaa1  ccc2 
ccc1  ddd2
eee2  aaa2
key: aaa1 with val: ccc2 found.