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     .................

实际数据不同,但这是它的简化版本。如您所见,有某些 Col1,其中 A1 是 A,但 A4 是 Y,依此类推。其余列 Col3、Col4 ... 取决于 Col2。因此,当 Col1 中有 A(A1、A2、A3 等)时,我需要检查 Col2 是否为 A。如果不是,我必须根据 A 所在的行更新 Col2、Col3 ....

如何在 Perl 中实现这一点。我知道这种操作可以在带有更新语句的数据库中完成,但我在这里没有那么奢侈,必须以编程方式完成。

编辑:文件是制表符分隔的,数据是可以包含任何字母数字或 ascii 字符的字符串。

4

4 回答 4

2

我这样做的方法是打开一个输入文件句柄和一个输出文件句柄,然后逐行检查文件检查列的第一列,如果没问题,就按原样将其放入我的输出中。

如果确实需要更改,我会用必要的更改创建一个新行并将其也放入我的输出文件中。

这是一种简单的方法,虽然不是最好的/优雅的/无论如何,可以快速为您提供所需的东西。

于 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 处理器!

至少Text::CSV或亲戚喜欢Text::CSV_XS(更快)或Text::CSV::Encoded(例如UTF-8)。

DBD::CSV提供 SQL。

于 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 回答