4

perl chomp 関数の問題に直面しています。以下のようなtest.csvがあります。

col1,col2
vm1,fd1
vm2,fd2
vm3,fd3
vm4,fd4

このcsvの2番目のフィールドを印刷したい。これは私のコードです:

#!/usr/bin/perl -w
use strict;

my $file = "test.csv";
open (my $FH, '<', $file);
my @array = (<$FH>);
close $FH;

foreach (@array)
{
    my @row = split (/,/,$_);
    my $var = chomp ($row[1]);     ###   <<< this is the problem
    print $var;
}

aboe コードの出力は次のとおりです。

11111

「1」がどこから来ているのか本当にわかりません。実際、最後のファイルは次のように印刷できます。

foreach (@array)
{
    my @row = split (/,/,$_);
    print $row[1];     ###  << Note that I am not printing "\n"
}  

出力は次のとおりです。

vm_cluster
fd1
fd2
fd3
fd4

現在、これらのフィールド値を DB への入力として使用していますが、この目に見えない改行が原因で DB INSERT ステートメントが失敗しています。だから私はchompがここで私を助けるだろうと思った. むしゃむしゃする代わりに、「11111」が表示されます。

ここで私が間違っていることを理解するのを手伝ってもらえますか。

ありがとう。

loldop の応答を読んだ後、さらに情報を追加します。

以下のように書くと、何も出力されません(上記の「11111」出力でさえありません)

foreach (@array)
{
    my @row = split (/,/,$_);
    chomp ($row[1]); 
    my $var = $row[1]; 
    print $var;
}

つまり、chomp は最後の文字列と末尾の改行を削除しています。

4

4 に答える 4

5

1s の文字列しか表示されない理由$valは、 から返される値の値を出力しているためですchompchompトリミングされた文字列を返すのではなく、そのパラメーターをインプレースで変更し、末尾から削除された文字数を返します。"\n"常に正確に 1文字を削除する1ため、配列の各要素の出力が得られます。

use warningsコマンドラインオプションの代わりに実際に使用する必要-wがあり、ファイル全体を配列に読み込む理由はありません。しかし、open.

これは、あなたが望むことを行うプログラムの簡単なリファクタリングです。

#!/usr/bin/perl
use strict;
use warnings;

my $file = 'test.csv';
open my $FH, '<', $file or die qq(Unable to open "$file": $!);

while (<$FH>) {
    chomp;
    my @row = split /,/;
    print $row[1], "\n";
}
于 2012-07-25T09:29:39.060 に答える
1

単に新しい行を削除したい場合は、正規表現を使用できます。

my $var = $row[1];
$var=~s/\n//g;
于 2012-07-25T08:44:32.337 に答える
1

とはいえ、最初は私のせいです。
chompfunction return 1<- この関数を使用した結果。
また、この悪い例を以下に示します。ただし、数字を使用すると機能します。時々私はこのチートを使用します(それをしないでください!これは私の悪いハックコードです!)
map{/filter/ && $_;}@all_to_filter;
これの代わりに、
grep{/filter/}@all_to_filter;

foreach (@array)
{
    my @row = split (/,/,$_);
    my $var = chomp ($row[1]) * $row[1];     ###   this is bad code!
    print $var;
}

foreach (@array)
{
    my @row = split (/,/,$_);
    chomp ($row[1]);
    my $var = $row[1];  
    print $var;
}
于 2012-07-25T08:41:30.737 に答える
0

だから、私はこの簡単に見えるタスクが一日中私を悩ませていたことにかなり不満を感じていました. 回答してくださった皆様、本当にありがとうございました。

最後に、Text::CSV perl モジュールを使用して、各 CSV フィールドを配列参照として呼び出しました。Text::CSV を使用した後、chomp を実行する必要はありませんでした。

コードは次のとおりです。

#!/usr/bin/perl 
use warnings;
use strict;
use Text::CSV;


 my $csv = Text::CSV->new ( { binary => 1 } )  # should set binary attribute.
                  or die "Cannot use CSV: ".Text::CSV->error_diag ();


open my $fh, "<:encoding(utf8)", "vm.csv" or die "vm.csv: $!";

<$fh>;  ## this is to remove the column headers.

while ( my $row = $csv->getline ($fh) )
{
    print $row->[1];
}

出力は次のとおりです。

fd1fd2fd3fd4 

後で、これらの個々の値が取得され、DB に挿入されました。

みんな、ありがとう。

于 2012-07-25T17:09:15.877 に答える