Perl脚本用于更新另一个文件的一行

时间:2011-02-07 16:33:48

标签: perl row fileparsing

我有文本格式的数据文件有几行。现在有些行有错误的数据,我需要更新那些具有正确数据的行。例如,

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.如果不是,我必须根据它所在的行更新Col2,Col3 ....

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

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

4 个答案:

答案 0 :(得分:2)

我这样做的方法是打开一个输入文件句柄和一个输出文件句柄,然后逐行浏览文件检查第一列,如果它很好,只需将它放入我的输出就好了。

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

这是一种简单的方法,虽然不是最伟大/优雅/无论什么,但它可以快速为您提供所需。

答案 1 :(得分:1)

填充键,其中键为Col2(A,B,C等),其值为其余列(Col3,Col4等)。如果Col1和Col2匹配,只能将Col2作为密钥。

然后在写出文件时,如果Col1和Col2不匹配,请在Col1的第一个字符的哈希中进行查找。这将为您提供要插入的Col3,Col4 ...值。

答案 2 :(得分:1)

使用CSV处理器!

至少Text::CSV或亲属,如Text::CSV_XS(更快)或Text::CSV::Encoded(例如,对于UTF-8)。

DBD::CSV提供SQL。

答案 3 :(得分: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>};
}

但你真的没有给予任何足够的帮助来帮助你。