2011-02-07 69 views
0

我有一些文本格式的數據文件,它們有幾行。現在有一些行有錯誤的數據,我需要使用那些具有正確數據的數據進行更新。例如,用另一個文件更新文件的一行的Perl腳本

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 ....基於它是A的行。

這怎麼可能在Perl中完成。我知道這種操作可以在具有更新語句的數據庫中完成,但我並沒有那麼奢侈,而必須以編程方式進行。

編輯:這些文件是製表符分隔的,數據是可以包含任何字母數字或ascii字符的字符串。

+0

請說明:數據是否存儲在空格分隔的文件中?單元格是否只能包含字母數字字符? A1的優先級高於A4,因爲它的編號較低,或者它的排較高? – Tim 2011-02-07 16:39:05

+0

我認爲你覺得你有點清楚,但是你說你可以在數據庫中這樣做,也許如果你發佈了類似的SQL,我們可以更好地瞭解1)你試圖更新什麼,2) ,3)在什麼條件下。 – Axeman 2011-02-07 17:20:08

+0

@Tim我添加了我似乎忘記添加的信息。這些單元格可能包含任何字符,而A1具有更高的優先權,因爲我知道Col2在這種情況下是A,所以它是手動查找的位。 – sfactor 2011-02-08 07:27:56

回答

2

我會這樣做的方式是打開一個輸入文件句柄和一個輸出文件句柄,然後逐行掃描文件檢查第一列,如果它很好,就把它放到我的輸出中就好了是。

如果確實需要更改,我會對所需的更改做一個新行並將其放入我的輸出文件中。

這是一個簡單的方法,雖然不是最偉大的/優雅的/無論什麼,會給你你需要的很快。

1

填充密鑰是Col2(A,B,C等),值是其餘列(Col3,Col4等)的散列圖。如果Col1和Col2匹配,只需將Col2設置爲關鍵字即可。

然後,如果Col1和Col2不匹配時寫出文件,請在Col1的第一個字符的散列中查找。這將爲您帶來Col3,Col4 ...值插入。

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>}; 
} 

但你真的沒有給任何人足夠的幫助來幫助你。

1

使用CSV處理器!

至少Text::CSV或諸如Text::CSV_XS(更快)或Text::CSV::Encoded(例如,對於UTF-8)的親屬。

DBD::CSV提供SQL。

相關問題