Perl:无法将输出写入文件

时间:2014-07-24 14:58:12

标签: perl

所以我有这个代码从命令行获取输入和输出文件,然后将某个输出写入输出文件(由于隐私问题,只显示此处显示的相关部分):

use strict;
use warnings;
use autodie;

# check that two arguments have been passed
die "usage: $0 input output\n" unless @ARGV == 2;

my $infile  = shift;
my $outfile = shift;

open my $in, "<", $infile;
open(DATA, $in);
open my $out, ">", $outfile;

my %DEF = (
    I   => [ qw( P Pl P.P P.Pl Pl.P Pl.Pl P.P.P P.P.Pl P.Pl.P P.Pl.Pl Pl. +P.P Pl.P.Pl Pl.Pl.P Pl.Pl.Pl ) ],
    II  => [ qw( E P.E Pl.E P.P.E P.Pl.E Pl.P.E Pl.Pl.E ) ],
    III => [ qw( E.P E.Pl P.E.P P.E.Pl Pl.E.P Pl.E.Pl E.P.P E.P.Pl E.Pl.P + E.Pl.Pl ) ],
    IV  => [ qw( E.E P.E.E Pl.E.E E.P.E E.Pl.E E.E.P E.E.Pl E.E.E ) ]
);
# Hash table/dictionary for all the  groups

my @rank  = map @$_, @DEF{qw(I II III IV)};
my %rank  = map { $rank[$_ - 1] => $_ } 1 .. @rank;
my @group = map { ($_) x @{ $DEF{$_} } } qw(I II III IV);
my %group = map { $rank[$_ - 1] => $group[$_ - 1] . "_" . $_ } 1 .. @group;

sub rank {
  $rank{ $a->[2] } <=> $rank{ $b->[2] }
}

my %T;

sub oh {
  map values %$_, @_;
}

sub ab {
  my ($b, $a) = @_;
  [$b->[0], $a->[1], qq($a->[2].$b->[2]), qq($b->[3]<-$a->[3])];
}

sub xtend {
  my $a = shift;
  map { ab $_, $a } oh @{ $T{ $a->[0] } }{@_};
}

sub ins {
  $T{ $_[3] //= $_[1] }{ $_[2] }{ $_[0] } = \@_;
}

ins split /,\s*/ for <DATA>;

#ins split /,\s*/ for $filename;
ins @$_ for map { xtend $_, qw(P E Pl) } (oh oh oh \%T);
ins @$_ for map { xtend $_, qw(P E Pl) } (oh oh oh \%T);

for (sort { rank } grep { $_->[1] eq 'Q' } (oh oh oh \%T)) {

  print $out "%-4s: %20s,   %-8s %6s\n",
      $_->[0],
      qq($_->[0]$_->[3]),
      $_->[2],
      $group{ $_->[2] };

  close $in;
  close $out;
}

问题是它没有向输出文件写任何东西。

perl program.pl input_file output_file

由于某些原因我想以格式读取输入文件,因此无法取消。

请帮忙

input_file
M19,Q,P,
M31,M19,Pl,
M420,M31,E,
M421,M31,E,
M33,M31,E,
M438,M33,Pl,
M445,M33,E,
M437,M33,E,
M444,M33,E,
M73,M33,E,
M552,M73,Pl,
M553,M73,Pl,
M569,M73,E,
M549,M73,E,
M550,M73,E,

1 个答案:

答案 0 :(得分:2)

我能看到的主要问题是这些

  • open(DATA, $in)毫无意义。我假设您要使用DATA文件句柄中的数据测试您的程序,在这种情况下您需要

    my $in = \*DATA;
    
  • 您正在关闭最终for循环中的两个文件句柄。这意味着只有一行将被写入输出,然后您将收到警告

    关闭文件句柄上的print()

  • 您正在使用print格式。您需要printf而不是

你的程序的这个变种修复了这些东西,并产生了一些输出。这是你的期望吗?

use strict;
use warnings;
use autodie;

# check that two arguments have been passed
# die "usage: $0 input output\n" unless @ARGV == 2;

my ($infile, $outfile) = @ARGV;
# open my $in_fh,  '<', $infile;
# open my $out_fh, '>', $outfile;

my $in_fh  = \*DATA;
my $out_fh = \*STDOUT;

my %DEF = (
    I   => [ qw( P Pl P.P P.Pl Pl.P Pl.Pl P.P.P P.P.Pl P.Pl.P P.Pl.Pl Pl. +P.P Pl.P.Pl Pl.Pl.P Pl.Pl.Pl ) ],
    II  => [ qw( E P.E Pl.E P.P.E P.Pl.E Pl.P.E Pl.Pl.E ) ],
    III => [ qw( E.P E.Pl P.E.P P.E.Pl Pl.E.P Pl.E.Pl E.P.P E.P.Pl E.Pl.P + E.Pl.Pl ) ],
    IV  => [ qw( E.E P.E.E Pl.E.E E.P.E E.Pl.E E.E.P E.E.Pl E.E.E ) ]
);
# Hash table/dictionary for all the  groups

my @rank  = map { @$_ }  @DEF{qw(I II III IV)};
my %rank  = map { $rank[$_ - 1] => $_ }  1 .. @rank;
my @group = map { ($_) x @{ $DEF{$_} } }  qw(I II III IV);
my %group = map { $rank[$_ - 1] => $group[$_ - 1] . "_" . $_ }  1 .. @group;

my %T;

sub rank {
  $rank{ $a->[2] } <=> $rank{ $b->[2] }
}

sub oh {
  map values %$_, @_;
}

sub ab {
  my ($b, $a) = @_;
  [ $b->[0], $a->[1], qq($a->[2].$b->[2]), qq($b->[3]<-$a->[3]) ];
}

sub xtend {
  my $a = shift;
  map { ab $_, $a } oh @{ $T{ $a->[0] } }{@_};
}

sub ins {
  $T{ $_[3] //= $_[1] }{ $_[2] }{ $_[0] } = \@_;
}

ins split /,\s*/ for <$in_fh>;
close $in_fh;

ins @$_ for map { xtend $_, qw(P E Pl) } (oh oh oh \%T);
ins @$_ for map { xtend $_, qw(P E Pl) } (oh oh oh \%T);

for (sort { rank } grep { $_->[1] eq 'Q' } (oh oh oh \%T)) {

  printf $out_fh "%-4s: %20s,   %-8s %6s\n",
      $_->[0],
      qq($_->[0]$_->[3]),
      $_->[2],
      $group{ $_->[2] };
}

close $out_fh;

__DATA__
M19,Q,P,
M31,M19,Pl,
M420,M31,E,
M421,M31,E,
M33,M31,E,
M438,M33,Pl,
M445,M33,E,
M437,M33,E,
M444,M33,E,
M73,M33,E,
M552,M73,Pl,
M553,M73,Pl,
M569,M73,E,
M549,M73,E,
M550,M73,E,

<强>输出

M19 :                 M19Q,   P           I_1
M31 :            M31M19<-Q,   P.Pl        I_4
M421:      M421M31<-M19<-Q,   P.Pl.E    II_20
M420:      M420M31<-M19<-Q,   P.Pl.E    II_20
M33 :       M33M31<-M19<-Q,   P.Pl.E    II_20