我有一个制表符分隔的文件1:
20 50 80 110
520 590 700 770
410 440 20 50
300 340 410 440
读取并将它们放入数组中:
while(<INPUT>)
{
chomp;
push @inputarray, $_;
}
现在我正在循环浏览另一个文件2:
20, 410, 700
80, 520
300
file2中每行的foreach编号,我想在@inputarray中搜索该编号。如果它存在,我想获取后面的相应数字。例如,对于数字20,我想要获取数字50.我假设它们仍然被字符串中的一个标签分隔,该标签在@inputarray中作为数组元素存在。
while(my $line = <INPUT2>)
{
chomp $line;
my @linearray = split("\t", $line);
foreach my $start (@linearray)
{
if (grep ($start, @inputarray))
{
#want to grab the corresponding number
}
}
}
一旦grep找到它,我不知道如何获取该数组元素以找到数字的位置以使用substr函数提取相应的数字。我如何获取grep找到的数组元素?
所需的输出是:
line1:
20 50
410 440
700 770
line2:
80 110
520 590
line3:
300 340
答案 0 :(得分:2)
恕我直言,最好将文件1中的数字存储在哈希中。参考上面提供的file1的示例clontent,您可以使用下面的内容
{
'20' => '50',
'80' => '110',
'520'=> '590',
'700'=> '770',
'410'=> '440',
'20' => '50',
'300'=> '340',
'410' => '440'
}
示例代码就像
my %inputarray;
while(<INPUT>)
{
my @numbers = split $_;
my $length = scalar $numbers;
# For $i = 0 to $i < $length;
# $inputarray{$numbers[$i]} = $numbers[$i+1];
# $i+=2;
}
上述循环的演示
index: 0 1 2 3
numbers: 20 50 80 110
first iteration: $i=0
$inputarray{$numbers[0]} = $numbers[1];
$i = 2; #$i += 2;
second iteration: $i=2
$inputarray{$numbers[2]} = $numbers[3];
然后在解析file2时,您只需要将该数字视为key
的{{1}}。
答案 1 :(得分:1)
我相信这会让你接近你想要的东西。
#!/usr/bin/perl -w
my %follows;
open my $file1, "<", $ARGV[0] or die "could not open $ARGV[0]: $!\n";
while (<$file1>)
{
chomp;
my $prev = undef;
foreach my $curr ( split /\s+/ )
{
$follows{$prev} = $curr if ($prev);
$prev = $curr;
}
}
close $file1;
open my $file2, "<", $ARGV[1] or die "could not open $ARGV[1]: $!\n";
my $lineno = 1;
while (<$file2>)
{
chomp;
print "line $lineno\n";
$lineno++;
foreach my $val ( split /,\s+/, $_ )
{
print $val, " ", ($follows{$val} // "no match"), "\n";
}
print "\n";
}
如果你只想考虑对中file1
的数字,而不是考虑哪些数字跟随其他数字而不考虑对边界,那么你需要改变逻辑在第一个while
循环中。
#!/usr/bin/perl -w
my %follows;
open my $file1, "<", $ARGV[0] or die "could not open $ARGV[0]: $!\n";
while (<$file1>)
{
chomp;
my $line = $_;
while ( $line =~ s/(\S+)\s+(\S+)\s*// )
{
$follows{$1} = $2;
}
}
close $file1;
open my $file2, "<", $ARGV[1] or die "could not open $ARGV[1]: $!\n";
my $lineno = 1;
while (<$file2>)
{
chomp;
print "line $lineno\n";
$lineno++;
foreach my $val ( split /,\s+/, $_ )
{
print $val, " ", ($follows{$val} // "no match"), "\n";
}
print "\n";
}
答案 2 :(得分:0)
如果您想要读取输入一次但是要检查数字,那么最好将split
输入行转换为单个数字。然后将每个数字作为键添加到哈希中,并使用以下数字作为值。这使得阅读速度变慢并且需要更多内存,但是由于exist
和哈希的性质,第二部分,您要检查以下数字将是轻而易举的。
如果我理解你的问题是正确的,你可以只使用一个大哈希。当然,假设每个数字后面都跟着相同的数字。