【问题标题】:Loop through 2 files perl循环遍历 2 个文件 perl
【发布时间】:2018-05-11 00:00:47
【问题描述】:

我在 Perl 中有一个问题。 2 个文件。

文件A

DistA,1010101,a_0200,Address,11,7
DistA,1010101,a_0200,Address,12,7
DistA,1010101,a_0200,Address,09,3
DistA,1010101,a_0200,Address,10,3
DistA,1010101,a_0200,Address,13,2
DistA,1010101,a_0300,Address,11,6
DistA,1010101,a_0300,Address,12,6
DistA,1010101,a_0300,Address,09,3
DistA,1010101,a_0300,Address,10,3
DistA,1010101,a_0300,Address,13,2
DistA,1010101,b_0200,Address,11,6
DistA,1010101,b_0200,Address,12,6
DistA,1010101,b_0200,Address,09,3
DistA,1010101,b_0200,Address,10,3
DistA,1010101,b_0200,Address,13,2
DistA,1010101,b_0300,Address,11,6
DistA,1010101,b_0300,Address,12,6
DistA,1010101,b_0300,Address,09,3
DistA,1010101,b_0300,Address,10,3
DistA,1010101,b_0300,Address,13,2

文件B

DistA,1010101,a_0200,23 
DistA,1010101,a_0300,21
DistA,1010101,b_0200,21 
DistA,1010101,b_0300,19

我得到的结果是这样的。

文件C

DistA,1010101,a_0200,Address,11,6
DistA,1010101,a_0200,Address,12,6
DistA,1010101,a_0200,Address,09,2
DistA,1010101,a_0200,Address,10,2
DistA,1010101,a_0200,Address,13,1
DistA,1010101,a_0300,Address,11,5
DistA,1010101,a_0300,Address,12,5
DistA,1010101,a_0300,Address,09,2
DistA,1010101,a_0300,Address,10,2
DistA,1010101,a_0300,Address,13,1
DistA,1010101,b_0200,Address,11,5
DistA,1010101,b_0200,Address,12,5
DistA,1010101,b_0200,Address,09,2
DistA,1010101,b_0200,Address,10,2
DistA,1010101,b_0200,Address,13,1
DistA,1010101,b_0300,Address,11,5
DistA,1010101,b_0300,Address,12,5
DistA,1010101,b_0300,Address,09,2
DistA,1010101,b_0300,Address,10,2
DistA,1010101,b_0300,Address,13,1

但是我希望每个结果都恰好在这个序列中,并从 FileB 的第 6 列中减去 1,如果值等于 0,我不需要打印。这只是一个示例,因为我需要 FileA 的每一行的类似结果

我想根据以下字段的匹配将 FileA 递减到 0。

DistA,1010101,a_0200.

所以减量是这样的。

文件新建C

Loop-1
DistA,1010101,a_0200,Address,11,7
DistA,1010101,a_0200,Address,12,7
DistA,1010101,a_0200,Address,09,3
DistA,1010101,a_0200,Address,10,3
DistA,1010101,a_0200,Address,13,2
Loop-2
DistA,1010101,a_0200,Address,11,6
DistA,1010101,a_0200,Address,12,6
DistA,1010101,a_0200,Address,09,2
DistA,1010101,a_0200,Address,10,2
DistA,1010101,a_0200,Address,13,1
Loop-3
DistA,1010101,a_0200,Address,11,5
DistA,1010101,a_0200,Address,12,5
DistA,1010101,a_0200,Address,09,1
DistA,1010101,a_0200,Address,10,1
Loop-4
DistA,1010101,a_0200,Address,11,4
DistA,1010101,a_0200,Address,12,4
Loop-5
DistA,1010101,a_0200,Address,11,3
DistA,1010101,a_0200,Address,12,3
Loop-6
DistA,1010101,a_0200,Address,11,2
DistA,1010101,a_0200,Address,12,2
Loop-7
DistA,1010101,a_0200,Address,11,1
DistA,1010101,a_0200,Address,12,1

我的 perl 在下面。

#!/usr/bin/perl

use strict;
use warnings;

$|=1;

my $filea = $ARGV[0];
my $fileb = $ARGV[1];


open ( FA, '<', $filea) || die ( "File $filea Not Found!" );
open ( FB, '<', $fileb) || die ( "File $fileb Not Found!" );
#open ( FC, ">", $filec) || die ( "File $filec Not Found!" );

my %hash;
while ( <FB> ) {
    chomp;
    my($dist, $sec, $cls, $max) = split ",";
    push @{ $hash{$dist, $sec, $cls} }, $max;
}

while ( <FA> ) {
    chomp;
    my($dist, $sec, $cls, $add, $idx, $qtd) = split ",";

    for my $max ( @{ $hash{$dist, $sec, $cls } }){
        my $tot = $qtd -1;
        print join(",", $dist, $sec, $cls, $add, $idx, $tot)."\n";
         $qtd=$tot;

    }
}

【问题讨论】:

  • 第二个 while 是我的 $max (@{ $hash{$dist, $sec, $cls} }){ my $tot = $qtd -1; print join(",", $dist, $sec, $cls, $add, $idx, $tot, $max )."\n"; $qtd=$tot; }
  • FileNewC 中没有最大值。你如何使用最大值?

标签: perl


【解决方案1】:

我想你想在这种情况下使用数组......所以代码如下所示。

#!/usr/bin/perl

use strict;
use warnings;

$|=1;

my $filea = $ARGV[0];
my $fileb = $ARGV[1];
my $action = $ARGV[2] || "n" ; 

open ( FA, '<', $filea) || die ( "File $filea Not Found!" );
open ( FB, '<', $fileb) || die ( "File $fileb Not Found!" );
#open ( FC, ">", $filec) || die ( "File $filec Not Found!" );

my @B;
while ( <FB> ) {
    chomp;
    my($dist, $sec, $cls, $max) = split ",";
    push @B, [$dist, $sec, $cls, $max];
}

my @A;
while ( <FA> ) {
    chomp;
    my($dist, $sec, $cls, $add, $idx, $qtd) = split ",";
    push @A, [$dist, $sec, $cls, $add, $idx, $qtd];
}

$i = 1;
my $j = 0;
my $k = 0;
while ( 1 ) {
    # -- keep looping til nothing is modified --
    my $modified=0;
    $j = 0;
    foreach my $row ( @A ) {
        # -- loop through FileA, $j is rowcount --
        $j++;
        $k=0;
        foreach my $line ( @B ) {
            # -- loop through FileB, $k is linecount --
            $k++;
            my $idx1= @$line[0].@$line[1].@$line[2];
            my $idx2= @$row[0].@$row[1].@$row[2];
            if ($idx1 eq $idx2) {
                # -- has to match on the index fields --
                my $max = @$line[3];
                my $tot = @$row[5] -1;
                if ( $tot > 0 ) {
                    # -- only print if modified and result is >0 --
                    # -- only print loop header if 1rst time through inside loop --
                    if (! $modified) { print "Loop-".$i++."\n"; }
                    if ($action eq "d") {
                        print "FileB[".$k."]: ".join(",", @$line[0],@$line[1],@$line[2],@$line[3] )."\n";
                        print "FileA[".$j."]: ".join(",", @$row[0],@$row[1],@$row[2],@$row[3],@$row[4],@$row[5]  )."\n";
                    }
                    print "*FileA[".$j."]: ".join(",", @$row[0],@$row[1],@$row[2],@$row[3],@$row[4],$tot )."\n";
                    @$row[5]=$tot;
                    $modified = 1;
                }
            }
        }
    }
    if ((! $modified ) || ($i > 50)) {
        # -- only exit if pass through entire loop with no modifications --
        # -- or we have looped too many times ... sanity check --
        last;
    }
}

查看第三个参数设置为“d”的额外细节调用

<filename> FileA FileB d

最终输出已配置为文件前缀和 Line# 以阐明正在修改的内容。

loop-1 的细节示例是 (注意修改后的行以 * 开头)

如果这不是您期望的顺序,那么我们必须对从 FileA 创建的二维数组进行预排序。如果是这种情况,您必须指定所需的排序顺序。

Loop-1
FileB[1]: DistA,1010101,a_0200,23 
FileA[1]: DistA,1010101,a_0200,Address,11,7
*FileA[1]: DistA,1010101,a_0200,Address,11,6
FileB[1]: DistA,1010101,a_0200,23 
FileA[2]: DistA,1010101,a_0200,Address,12,7
*FileA[2]: DistA,1010101,a_0200,Address,12,6
FileB[1]: DistA,1010101,a_0200,23 
FileA[3]: DistA,1010101,a_0200,Address,09,3
*FileA[3]: DistA,1010101,a_0200,Address,09,2
FileB[1]: DistA,1010101,a_0200,23 
FileA[4]: DistA,1010101,a_0200,Address,10,3
*FileA[4]: DistA,1010101,a_0200,Address,10,2
FileB[1]: DistA,1010101,a_0200,23 
FileA[5]: DistA,1010101,a_0200,Address,13,2
*FileA[5]: DistA,1010101,a_0200,Address,13,1
FileB[2]: DistA,1010101,a_0300,21
FileA[6]: DistA,1010101,a_0300,Address,11,6
*FileA[6]: DistA,1010101,a_0300,Address,11,5
FileB[2]: DistA,1010101,a_0300,21
FileA[7]: DistA,1010101,a_0300,Address,12,6
*FileA[7]: DistA,1010101,a_0300,Address,12,5
FileB[2]: DistA,1010101,a_0300,21
FileA[8]: DistA,1010101,a_0300,Address,09,3
*FileA[8]: DistA,1010101,a_0300,Address,09,2
FileB[2]: DistA,1010101,a_0300,21
FileA[9]: DistA,1010101,a_0300,Address,10,3
*FileA[9]: DistA,1010101,a_0300,Address,10,2
FileB[2]: DistA,1010101,a_0300,21
FileA[10]: DistA,1010101,a_0300,Address,13,2
*FileA[10]: DistA,1010101,a_0300,Address,13,1
FileB[3]: DistA,1010101,b_0200,21 
FileA[11]: DistA,1010101,b_0200,Address,11,6
*FileA[11]: DistA,1010101,b_0200,Address,11,5
FileB[3]: DistA,1010101,b_0200,21 
FileA[12]: DistA,1010101,b_0200,Address,12,6
*FileA[12]: DistA,1010101,b_0200,Address,12,5
FileB[3]: DistA,1010101,b_0200,21 
FileA[13]: DistA,1010101,b_0200,Address,09,3
*FileA[13]: DistA,1010101,b_0200,Address,09,2
FileB[3]: DistA,1010101,b_0200,21 
FileA[14]: DistA,1010101,b_0200,Address,10,3
*FileA[14]: DistA,1010101,b_0200,Address,10,2
FileB[3]: DistA,1010101,b_0200,21 
FileA[15]: DistA,1010101,b_0200,Address,13,2
*FileA[15]: DistA,1010101,b_0200,Address,13,1
FileB[4]: DistA,1010101,b_0300,19
FileA[16]: DistA,1010101,b_0300,Address,11,6
*FileA[16]: DistA,1010101,b_0300,Address,11,5
FileB[4]: DistA,1010101,b_0300,19
FileA[17]: DistA,1010101,b_0300,Address,12,6
*FileA[17]: DistA,1010101,b_0300,Address,12,5
FileB[4]: DistA,1010101,b_0300,19
FileA[18]: DistA,1010101,b_0300,Address,09,3
*FileA[18]: DistA,1010101,b_0300,Address,09,2
FileB[4]: DistA,1010101,b_0300,19
FileA[19]: DistA,1010101,b_0300,Address,10,3
*FileA[19]: DistA,1010101,b_0300,Address,10,2
FileB[4]: DistA,1010101,b_0300,19
FileA[20]: DistA,1010101,b_0300,Address,13,2
*FileA[20]: DistA,1010101,b_0300,Address,13,1
Loop-2

【讨论】:

  • 我知道你的想法非常好,但仍然行不通。我从 FileB 中仅对 DistA,1010101,a_0200,23 行得到的结果是: DistA,1010101,a_0200,Address,11,6 DistA,1010101,a_0200,Address,12,6 DistA,1010101,a_0200,Address,09 ,2 DistA,1010101,a_0200,Address,10,2 DistA,1010101,a_0200,Address,13,1 我需要从第 6 列开始排序,在这种情况下,结果 (11=>6,12=>6 ,09=>2,10=>2,13=>1)。但是我需要从 FileA 开始的每个值递减 -1,直到所有位置都变为 0。
  • 我通过 $qtd foreach my $line (@h) { my $max = @$line[3]; 在 foreach 中放了另一个 for我的 $tot = $qtd -1; for (1..$qtd){ if ( $tot > 0 ) { print join(",", $dist, $sec, $cls, $add, $idx, $tot, $max )."\n" ; $qtd=$tot; } }
  • 我得到了一个近似的结果,但不是我想要的那种。 Loop-1 DistA,1010101,a_0200,Address,11,6 DistA,1010101,a_0200,Address,11,6 DistA,1010101,a_0200,Address,11,6 DistA,1010101,a_0200,Address,11,6 DistA,1010101 ,a_0200,Address,11,6 DistA,1010101,a_0200,Address,11,6 DistA,1010101,a_0200,Address,11,6 Loop-2 DistA,1010101,a_0200,Address,12,6 DistA,1010101,a_0200, Address,12,6 DistA,1010101,a_0200,Address,12,6 DistA,1010101,a_0200,Address,12,6 DistA,1010101,a_0200,Address,12,6 DistA,1010101,a_0200,Address,12,6 DistA ,1010101,a_0200,Address,12,6 等等。
  • 但正确的是:Loop-1 DistA,1010101,a_0200,Address,11,7 DistA,1010101,a_0200,Address,12,7 DistA,1010101,a_0200,Address,09,3 DistA ,1010101,a_0200,Address,10,3 DistA,1010101,a_0200,Address,13,2 Loop-2 DistA,1010101,a_0200,Address,11,6 DistA,1010101,a_0200,Address,12,6 DistA,1010101, a_0200,Address,09,2 DistA,1010101,a_0200,Address,10,2 DistA,1010101,a_0200,Address,13,1 等等。
  • 对不起....目前尚不清楚您使用的是哪种类型。您是否想说您希望在处理之前根据第 6 列按降序对 FileA 行进行排序,然后只处理具有第一个(最大值)值的行?
猜你喜欢
  • 2016-08-20
  • 2021-12-06
  • 2013-12-11
  • 1970-01-01
  • 2019-07-21
  • 2019-01-03
  • 2018-01-15
  • 2021-12-09
  • 1970-01-01
相关资源
最近更新 更多