Perl скрипт для обновления одной строки файла другой - PullRequest
0 голосов
/ 07 февраля 2011

У меня есть файлы данных в текстовом формате, которые имеют несколько строк.Теперь есть определенные строки, которые содержат неправильные данные, которые мне нужно обновить с теми, которые имеют правильные данные.Например,

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.Итак, мне нужно проверить, является ли Col2 A, когда есть A в Col1 (A1, A2, A3 и т. Д.).Если нет, я должен обновить Col2, Col3 .... в зависимости от строки, где это A.

Как это можно сделать в Perl.Я знаю, что такого рода операции можно выполнять в базе данных с помощью оператора update, но у меня нет такой роскоши, и мне приходится делать это программно.

Редактировать: файлы с разделителями табуляции иданные - это строки, которые могут содержать любой буквенно-цифровой символ или символ ascii.

Ответы [ 4 ]

2 голосов
/ 07 февраля 2011

Я бы сделал это, открыв дескриптор входного файла и дескриптор выходного файла, и построчно перебирая один столбец проверки файлов, и, если это нормально, просто вставьте его в мой вывод, как есть.

Если это действительно нужно изменить, я бы сделал новую строку с необходимыми изменениями и поместил бы ее также в свой выходной файл.

Это простой подход, который хотя и не самый лучший/ Elegant / что угодно, даст вам то, что вам нужно быстро.

1 голос
/ 08 февраля 2011

Используйте процессор CSV!

По крайней мере Text::CSV или родственники, такие как Text::CSV_XS (быстрее) или Text::CSV::Encoded (например, для UTF-8).

DBD::CSV обеспечиваетSQL.

1 голос
/ 07 февраля 2011

Заполните хэш-карту, где ключом является Col2 (A, B, C и т. Д.), А значением являются остальные столбцы (Col3, Col4 и т. Д.). Делайте Col2 ключом, только если Col1 и Col2 совпадают так, как вы хотите.

Затем при записи файла, если Col1 и Col2 не совпадают, выполните поиск в хэше первого символа Col1. Вы получите значения Col3, Col4 ... для вставки.

0 голосов
/ 07 февраля 2011

Ниже приведен каркас базовой структуры программы, позволяющий вам сделать это. Если бы я знал, что ты хотел сделать, я был бы намного более полезным.

Я сделал простейшее предположение из возможных, и обработал ваши входные файлы так, как если бы они были фиксированными столбцами с шириной = 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>};
}

Но вы действительно никому не помогли.

...