Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.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
Arrays 跳过数组中的一行,Perl_Arrays_Perl_File_Csv_Compare - Fatal编程技术网

Arrays 跳过数组中的一行,Perl

Arrays 跳过数组中的一行,Perl,arrays,perl,file,csv,compare,Arrays,Perl,File,Csv,Compare,我对Perl还比较陌生,我遇到了这个项目,我有点难以处理。 本项目的目的是比较两个csv文件,其中一个包含: $name、$model、$version 另一个将包含: $name2,$disk,$storage 最后,结果文件将包含匹配的行,并将如下信息组合在一起: $name、$model、$version、$disk、$storage 我已经设法做到了这一点,但我的问题是,当缺少程序中的一个元素中断时。当它遇到文件中缺少元素的行时,它将停止在该行。我如何解决这个问题?有什么建议或方法可以让

我对Perl还比较陌生,我遇到了这个项目,我有点难以处理。 本项目的目的是比较两个csv文件,其中一个包含: $name、$model、$version 另一个将包含: $name2,$disk,$storage 最后,结果文件将包含匹配的行,并将如下信息组合在一起: $name、$model、$version、$disk、$storage

我已经设法做到了这一点,但我的问题是,当缺少程序中的一个元素中断时。当它遇到文件中缺少元素的行时,它将停止在该行。我如何解决这个问题?有什么建议或方法可以让我跳过这一行继续吗

这是我的密码:

open( TESTING, '>testing.csv' ); # Names will be printed to this during testing. only .net       ending names should appear
open( MISSING, '>Missing.csv' ); # Lines with missing name feilds will appear here.

#open (FILE,'C:\Users\hp-laptop\Desktop\file.txt');
#my (@array) =<FILE>;
my @hostname;    #stores names

#close FILE;
#***** TESTING TO SEE IF ANY OF THE LISTED ITEMS BEGIN WITH A COMMA AND DO NOT HAVE A   NAME.
#***** THESE OBJECTS ARE PLACED INTO THE MISSING ARRAY AND THEN PRINTED OUT IN A SEPERATE
#***** FILE.
#open (FILE,'C:\Users\hp-laptop\Desktop\file.txt');
#test
if ( open( FILE, "file.txt" ) ) {

}
else {
  die " Cannot open file 1!\n:$!";

}

$count = 0;
$x     = 0;
while (<FILE>) {

  ( $name, $model, $version ) = split(",");    #parsing

  #print $name;
  chomp( $name, $model, $version );

  if ( ( $name =~ /^\s*$/ )
      && ( $model   =~ /^\s*$/ )
      && ( $version =~ /^\s*$/ ) )    #if all of the fields  are blank ( just a blank space)
  {

    #do nothing at all
  }
  elsif ( $name =~ /^\s*$/ ) {   #if name is a blank
    $name =~ s/^\s*/missing/g;
    print MISSING "$name,$model,$version\n";

    #$hostname[$count]=$name;
    #$count++;
  }
  elsif ( $model =~ /^\s*$/ ) {   #if model is blank
    $model =~ s/^\s*/missing/g;
    print MISSING"$name,$model,$version\n";
  }
  elsif ( $version =~ /^\s*$/ ) {   #if version is blank
    $version =~ s/^\s*/missing/g;
    print MISSING "$name,$model,$version\n";
  }

  # Searches for .net to appear in field "$name" if match, it places it into hostname array.
  if ( $name =~ /.net/ ) {

    $hostname[$count] = $name;
    $count++;
  }

#searches for a comma in the name feild, puts that into an array and prints the line into the missing file.
#probably won't have to use this, as I've found a better method to test all of the    feilds ( $name,$model,$version)
#and put those into the missing file. Hopefully it works.
#foreach $line (@array)
#{
#if($line =~ /^\,+/)
#{
#$line =~s/^\,*/missing,/g;
#$missing[$x]=$line;
#$x++;
#}
#}

}
close FILE;

for my $hostname (@hostname) {
  print TESTING $hostname . "\n";
}

#for my $missing(@missing)
#{
# print MISSING $missing;
#}
if ( open( FILE2, "file2.txt" ) ) {    #Run this if the open succeeds

  #open outfile and print starting header
  open( RESULT, '>resultfile.csv' );
  print RESULT ("name,Model,version,Disk, storage\n");
}
else {
  die " Cannot open file 2!\n:$!";
}
$count = 0;
while ( $hostname[$count] ne "" ) {
  while (<FILE>) {
    ( $name, $model, $version ) = split(",");    #parsing

    #print $name,"\n";

    if ( $name eq $hostname[$count] )    # I think this is the problem area.
    {
      print $name, "\n", $hostname[$count], "\n";

      #print RESULT"$name,$model,$version,";
      #open (FILE2,'C:\Users\hp-laptop\Desktop\file2.txt');
      #test
      if ( open( FILE2, "file2.txt" ) ) {

      }
      else {
        die " Cannot open file 2!\n:$!";

      }

      while (<FILE2>) {
        chomp;
        ( $name2, $Dcount, $vname ) = split(",");    #parsing

        if ( $name eq $name2 ) {
          chomp($version);
          print RESULT"$name,$model,$version,$Dcount,$vname\n";

        }

      }

    }

    $count++;
  }

  #open (FILE,'C:\Users\hp-laptop\Desktop\file.txt');
  #test
  if ( open( FILE, "file.txt" ) ) {

  }
  else {
    die " Cannot open file 1!\n:$!";

  }

}

close FILE;
close RESULT;
close FILE2;
open(TESTING,'>TESTING.csv');#在测试过程中,名称将打印到此页面。只应显示.net结尾名称
打开(缺少“>MISSING.csv”);#此处将显示缺少名称feilds的行。
#打开(文件'C:\Users\hp laptop\Desktop\FILE.txt');
#我的(@array)=;
我的@hostname#存储名称
#关闭文件;
#*****测试以查看列出的项目中是否有以逗号开头且没有名称的项目。
#*****这些对象被放入丢失的数组中,然后以单独的格式打印出来
#*****文件。
#打开(文件'C:\Users\hp laptop\Desktop\FILE.txt');
#试验
如果(打开(文件“FILE.txt”)){
}
否则{
die“无法打开文件1!\n:$!”;
}
$count=0;
$x=0;
而(){
($name,$model,$version)=拆分(“,”);解析
#打印$name;
chomp($name,$model,$version);
如果($name=~/^\s*$/)
&&($model=~/^\s*$/)
&&($version=~/^\s*$/)#如果所有字段都是空的(只有一个空格)
{
#什么也不做
}
elsif($name=~/^\s*$/){#如果名称为空
$name=~s/^\s*/missing/g;
打印缺少“$name,$model,$version\n”;
#$hostname[$count]=$name;
#$count++;
}
elsif($model=~/^\s*$/){#如果model为空
$model=~s/^\s*/missing/g;
打印缺少“$name,$model,$version\n”;
}
elsif($version=~/^\s*$/){#如果version为空
$version=~s/^\s*/missing/g;
打印缺少“$name,$model,$version\n”;
}
#搜索.net以显示在字段“$name”中。如果匹配,则将其放入主机名数组中。
如果($name=~/.net/){
$hostname[$count]=$name;
$count++;
}
#在名称feild中搜索逗号,将其放入数组并将该行打印到缺少的文件中。
#可能不必使用这个,因为我找到了一个更好的方法来测试所有的feild($name,$model,$version)
#然后把它们放到丢失的文件里,希望它能起作用。
#foreach$行(@array)
#{
#如果($line=~/^\,+/)
#{
#$line=~s/^\,*/缺失,/g;
#$missing[$x]=$line;
#$x++;
#}
#}
}
关闭文件;
对于我的$hostname(@hostname){
打印测试$hostname。“\n”;
}
#我的$missing(@missing)
#{
#打印丢失的$MISSING;
#}
如果(打开(FILE2,“FILE2.txt”){#如果打开成功,请运行此命令
#打开输出文件并打印起始标题
打开(结果'>resultfile.csv');
打印结果(“名称、型号、版本、磁盘、存储\n”);
}
否则{
die“无法打开文件2!\n:$!”;
}
$count=0;
而($hostname[$count]ne“”){
而(){
($name,$model,$version)=拆分(“,”);解析
#打印$name,“\n”;
如果($name eq$hostname[$count]),我认为这就是问题所在。
{
打印$name、“\n”、$hostname[$count]、“\n”;
#打印结果“$name,$model,$version”;
#打开(文件2,'C:\Users\hp laptop\Desktop\FILE2.txt');
#试验
如果(打开(FILE2,“FILE2.txt”)){
}
否则{
die“无法打开文件2!\n:$!”;
}
而(){
咀嚼;
($name2,$Dcount,$vname)=拆分(“,”)#解析
如果($name eq$name2){
chomp($版本);
打印结果“$name、$model、$version、$Dcount、$vname\n”;
}
}
}
$count++;
}
#打开(文件'C:\Users\hp laptop\Desktop\FILE.txt');
#试验
如果(打开(文件“FILE.txt”)){
}
否则{
die“无法打开文件1!\n:$!”;
}
}
关闭文件;
接近结果;
关闭文件2;
我想您需要,它可以让您立即完成当前迭代并开始下一个迭代:

while (<FILE>) {
  ( $name, $model, $version ) = split(",");
  next unless( $name && $model && $version );
  ...;
  }
while(){
($name,$model,$version)=拆分(“,”);
下一个除非($name&&$model&&$version);
...;
}
您使用的条件取决于您将接受的值。在我的示例中,我假设所有值都必须为true。如果它们不需要是空字符串,您可以检查长度:

while (<FILE>) {
  ( $name, $model, $version ) = split(",");
  next unless( length($name) && length($model) && length($version) );
  ...;
  }
while(){
($name,$model,$version)=拆分(“,”);
下一步除非(长度($name)&&length($model)&&length($version));
...;
}
如果您知道如何验证每个字段,则可能会有以下子例程:

while (<FILE>) {
  ( $name, $model, $version ) = split(",");
  next unless( length($name) && is_valid_model($model) && length($version) );
  ...;
  }

sub is_valid_model { ... }
while(){
($name,$model,$version)=拆分(“,”);
下一步除非(长度($name)和有效性($model)和长度($version));
...;
}
sub是有效的模型{…}

现在,您只需要决定如何将其集成到您已经在做的事情中。

您应该首先在程序顶部添加
use strict
use warnings
,并在第一次使用时用
my
声明所有变量。这将揭示出许多简单的错误,否则很难发现

您还应该为of
open
和lexicalfilehandles使用三个参数,用于检查打开文件时的异常的Perl习惯用法是将
或die
添加到
open
调用中<代码>如果语句中包含成功路径的空块,则会浪费空间并变得无法读取。
open
调用应该如下所示

open my $fh, '>', 'myfile' or die "Unable to open file: $!";
最后,在处理CSV文件时使用Perl模块要安全得多,因为使用简单的
split/,/
有很多陷阱。该模块已为您完成所有工作,可在CPAN上使用

你的问题是,拥有真正的
use strict;
use warnings;

use Text::CSV;

my $csv = Text::CSV->new;

my %data;

# Read the name, model and version from the first file. Write any records
# that don't have the full three fields to the "MISSING" file
#
open my $f1, '<', 'file.txt' or die qq(Cannot open file 1: $!);

open my $missing, '>', 'Missing.csv' 
    or die qq(Unable to open "MISSING" file for output: $!);
    # Lines with missing name fields will appear here.

while ( my $line = csv->getline($f1) ) {

  my $name = $line->[0];

  if (grep $_, @$line < 3) {
    $csv->print($missing, $line);
  }
  else {
    $data{$name} = $line if $name =~ /\.net$/i;
  }
}

close $missing;

# Put a list of .net names found into the testing file
#
open my $testing, '>', 'testing.csv'
    or die qq(Unable to open "TESTING" file for output: $!);
    # Names will be printed to this during testing. Only ".net" ending names should appear

print $testing "$_\n" for sort keys %data;

close $testing;

# Read the name, disk and storage from the second file and check that the line
# contains all three fields. Remove the name field from the start and append
# to the data record with the matching name if it exists.
#
open my $f2, '<', 'file2.txt' or die qq(Cannot open file 2: $!);

while ( my $line = $csv->getline($f2) ) {

  next unless grep $_, @$line >= 3;

  my $name = shift @$line;
  next unless $name =~ /\.net$/i;

  my $record = $data{$name};
  push @$record, @$line if $record;
}

# Print the completed hash. Send each record to the result output if it
# has the required five fields
#
open my $result, '>', 'resultfile.csv' or die qq(Cannot open results file: $!);

$csv->print($result, qw( name Model version Disk storage ));

for my $name (sort keys %data) {

  my $line = $data{$name};

  if (grep $_, @$line >= 5) {
    $csv->print($result, $data{$name});
  }
}