0

複数の行を持つテキスト形式のデータ ファイルがあります。現在、間違ったデータを持つ特定の行があり、正しいデータを持つ行で更新する必要があります。例えば、

Col1  Col2  Col3  Col4 .......
A1?%     A     foo  fooo .......
B€(2     B     .................  
C&6     Z     .................
A?04     Y     .................
B++3     Q     .................
C!5     C     .................
D*9     D     .................

実際のデータは異なりますが、これは単純化されたバージョンです。ご覧のとおり、A1 が A で A4 が Y などの特定の Col1 があります。残りの列 Col3、Col4 ... は Col2 に依存します。したがって、Col1 に A がある場合 (A1、A2、A3 など)、Col2 が A であるかどうかを確認する必要があります。そうでない場合は、A である行に基づいて Col2、Col3 .... を更新する必要があります。

これを Perl でどのように実現できますか。この種の操作は update ステートメントを使用してデータベースで実行できることは知っていますが、ここではその余裕がなく、プログラムで実行する必要があります。

編集: ファイルはタブ区切りで、データは任意の英数字または ASCII 文字を含むことができる文字列です。

4

4 に答える 4

2

これを行う方法は、入力ファイルハンドルと出力ファイルハンドルを開き、ファイルチェック列1を1行ずつ調べて、問題がない場合は、そのまま出力に挿入することです。

変更する必要がある場合は、必要な変更を加えた新しい行を作成し、それを出力ファイルにも入れます。

これは単純なアプローチであり、最高/エレガント/何でもありませんが、必要なものをすばやく提供します。

于 2011-02-07T16:39:31.343 に答える
1

キーが Col2 (A、B、C など) で、値が残りの列 (Col3、Col4 など) であるハッシュマップを作成します。Col1 と Col2 が必要に応じて一致する場合にのみ、Col2 をキーにします。

次に、Col1 と Col2 が一致しない場合にファイルを書き出すときに、Col1 の最初の文字でハッシュを検索します。これにより、挿入する Col3、Col4... の値が取得されます。

于 2011-02-07T16:45:21.503 に答える
1

CSVプロセッサを使用してください!

少なくともまたは(より速い)または(UTF-8の場合など)Text::CSVのような親戚。Text::CSV_XSText::CSV::Encoded

DBD::CSVSQL を提供します。

于 2011-02-08T08:51:56.167 に答える
0

以下は、これを可能にする基本的なプログラム構造のスケルトンです。あなたが何をしたいのかを知っていれば、私はもっと役に立ちます。

可能な限り簡単な推測を行い、入力ファイルを、幅が 7,6,* の固定列であるかのように扱いました。タブ区切りであることをお知らせいただいたので、データをフィールドに分割するコードを変更しました。

use autodie;
use strict;
use warnings;
use English qw<$INPUT_LINE_NUMBER>;

my %data;
my $line_no;
open ( my $h, '<', 'good_file.dat' );

while ( <$h> ) {
    my ( $col1, $col2, $data ) = split( /\t+/, $_, 3 );
    # next unless index( $col1, 'A' ) == 0;
    $line_no = $INPUT_LINE_NUMBER;
    my $rec 
        = { col1 => $col1
          , col2 => $col2
          , data => $data
          , line => $line_no
          };
    push( @{ $data{"$col1-$col2"} }, $rec );
    $data{ $line_no } = $rec;
}
close $h;

open ( $h, '<', 'old_file.dat' );

while ( <$h> ) { 
    my ( $col1, $col2, $data ) = split( /\t+/, $_, 3 );
    ... 
}

以下は、値をファイルに出力する方法です。

open ( $h, '>', 'old_file.dat' );
foreach my $rec ( grep {; defined } @data{ 1..$line_no } ) { 
    printf $h "%s\t%s\t%s\n", @$rec{qw<col1 col2 data>};
}

しかし、あなたは本当にあなたを助けるのに十分な助けを誰にも与えていません。

于 2011-02-07T19:33:20.427 に答える