特定の文字を含む配列全体を削除する方法

特定の文字を含む配列全体を削除する方法

.xlsファイルから抽出されたPerlコードがあります。私の.xlsファイルは次のとおりです

NUMBER    NAME    ALPHABET
one       Jane        a
two       Adam        b
three     Josh        c
;four  
five      Agnes       e 
six       Mary        f
;seven 
eight     Lara        h        

情報を抽出し、1列と2列だけをインポートしたいと思います。私のPerlコードは次のようになります。

     #!/usr/bin/perl

     use warnings;
     use strict;
     use Spreadsheet::ParseExcel;

     main ();

     sub main {

        my $filename = 'Book1.xls';
        my $parser   = Spreadsheet::ParseExcel->new();
        my $workbook = $parser->parse( $filename );

        if ( !defined $workbook ) {
           die "-E-: cannot parse <$filename>.\n ", $parser->error(), ".\n";
        }

        my $worksheet             = $workbook -> Worksheet ( 'a' ) || die "-E-: cannot parse family pin list.\n";   
        my ( $row_min, $row_max ) = $worksheet-> row_range();

        open ( my $file,"> output.txt");

        for my $row ( 1 .. $row_max ) {

           my @data;

           for my $col ( 0 ) {
              my $number = $worksheet-> get_cell( $row, $col );
              if ( $number ) {
                 push @data, $number-> value();
              }
              else {
                 push @data, '';
              }
            }

            for my $col ( 2 ) {
               my $alphabet = $worksheet->get_cell( $row, $col );
               if ( $alphabet ) {
                  push @data, $alphabet->value();
                  print $file  "@data\n";
               }
               else {
               push @data, '';
               }
            }     

     }

     close $file;

      print "done\n";
     }

明らかにする

    one a
    two b
    three c
    ;four 
    five e
    six f
    ;seven 
    eight h

文字列 ";"で始まる配列全体を削除したいと思います。以下のようにコードを展開します。

        open ( my $file,"> output.txt");

        for my $row ( 1 .. $row_max ) {

           my @data;

           for my $col ( 0 ) {
              my $number = $worksheet-> get_cell( $row, $col );
              if ( $number ) {
                 push @data, $number-> value();
              }
              else {
                 push @data, '';
              }
            }

            for my $col ( 11 ) {
               my $alphabet = $worksheet->get_cell( $row, $col );
               if ( $alphabet ) {
                  push @data, $alphabet->value();
               }
               else {
               push @data, '';
               }
            }


      my @new_data = grep(!/;/, @data);
      my @latest_data = grep ( $_ ne '', @new_data);
      print $file  "@latest_data\n";


     }

     close $file;

      print "done\n";
     }

出力は以下の通りです。

     one a
     two b
     three c

     five e
     six f

     eight h

白紙の状態になりたくありません。次の結果を生成するスペースを削除するにはどうすればよいですか?

     one a
     two b
     three c
     five e
     six f
     eight h

私もこうしてみましたが、結果は同じですね。

     for my $index (reverse 0..$#data) {
        if ( $data[$index] =~ /^;/ ) {
        splice(@data, $index, 1);
       }
     }
     print $file "@data\n";

答え1

残りの列を繰り返す前に、現在の行の列0を確認することをお勧めします。値がセミコロンで始まる場合は、次の行にスキップします。

   # ...

   for my $row ( 1 .. $row_max ) {

       my @data;
       next if $worksheet->get_cell($row, 0) =~ /^;/;

   # ...

これにより、新しい(行)データが配列にプッシュされるのを防ぎます。

答え2

この結果を得るには、次のものを使用できますawk

awk '$1 !~ "NUMBER" && $1 !~ "^;" {print $1,$3}' file.xls

NUMBERこれは、対応する文字列を含むかで始まる項目を印刷しないように指示します;。次に、最初と3番目の列を印刷し、期待される出力を提供します。

one a
two b
three c
five e
six f
eight h

関連情報