3

仕事用に、ベンダーのアップグレードによって変更されたいくつかの CSV ファイルがあり、以前よりも約 80 列多く含まれています。欠点は、これらのファイルが請求に使用されるため、新しい列を削除する必要があることです。利点は、すべての列がレコードの最後に追加されたことです。古いレコードには 251 列が含まれていました。新しいレコードには 336 が含まれています。

したがって、私が書いているスクリプトは、CSV ファイル名を引数として受け入れ、ファイルが非常に大きくなる可能性があるため、その場で編集し、最初の 2 行と最後の行を削除し、最後に新しい列を削除します (内容を空にするだけではありません)。 、それらを完全に削除するため、元の形式に N 列があった場合、処理後の新しい形式には N 列のみが含まれる必要があります)

これが私がこれまでに持っているものです:

use strict;
use warnings;

#Use Tie::File to modify file contents directly on disk, without reading
#to memory.
use Tie::File;

#Use Text::CSV_XS to quickly remove columns from CSV. External library
#used to compensate for quoted fields.
use Text::CSV_XS;

my $csvparser = Text::CSV_XS->new () or die "".Text::CSV_XS->error_diag();
my $file;

foreach $file (@ARGV){
        my @CSVFILE;
        my $csvparser = Text::CSV_XS->new () or die "".Text::CSV_XS->error_diag();
        tie @CSVFILE, 'Tie::File', $file or die $!;
        shift @CSVFILE;
        shift @CSVFILE;
        pop @CSVFILE;
        for my $line (@CSVFILE) {
                $csvparser->parse($line);
                my @fields = $csvparser->fields;
                splice @fields, -85;
                $line = $csvparser->combine(@fields);
        }

        untie @CSVFILE;
}

これが実行され、最初の部分が正しく実行されます (最初の 2 行と最後の行を削除します)。ただし、新しい列の削除を続行する方法がわかりません。Text::CSV_XS のドキュメントを読んでいますが、列を削除する関数が見つからないようです。いくつかの例は役に立つかもしれませんが、私の perl スキルはあまり良くありません。モジュールを使用したい主な理由は、これらの CSV ファイルには、モジュールが処理できる引用符で囲まれたコンマ付きのフィールドが含まれている場合があるためです。

これにアプローチする方法についての提案は素晴らしいでしょう。また、私のアプローチに問題がある場合は、お知らせください。私は決して perl の専門家ではありません。また、これは課金システムに組み込まれるため、有益な批判を歓迎します。

編集:以下からの提案をコードに含めました。以下で説明するように、これを実行すると、ソース ファイルの内容がすべての行で単一の「1」に置き換えられます。

4

1 に答える 1

4

はい、あなたが求めることはできますが、私はそれ以上の速度を望んでいません.

このようなものが動作するはずです

use strict;
use warnings;

use Tie::File;
use Text::CSV_XS;

my $csv = Text::CSV_XS->new or die Text::CSV_XS->error_diag;

foreach my $file (@ARGV) {

    tie my @lines, 'Tie::File', $file or die $!;

    splice @lines, 0, 2;
    pop @lines;

    for my $line (@lines) {
        $csv->parse($line);
        my @fields = $csv->fields;
        splice @fields, -80;
        $csv->combine(@fields);
        $line = $csv->string;
    }

    untie @lines;
}
于 2013-05-22T16:57:33.077 に答える