仕事用に、ベンダーのアップグレードによって変更されたいくつかの 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」に置き換えられます。