Преобразование нерегулярных данных в структурированную таблицу с помощью Perl - PullRequest
2 голосов
/ 03 марта 2012

Я хотел бы преобразовать следующие строки данных в структурированную таблицу с помощью perl:

3=884|4=884|5=MBREFUSDCMR|25=113500|824=20120229|387=4.15|248=TLD|280=5
3=884|4=884|5=MBREFUSDCMR|24=1|12=0|10=0|25=113500|824=20120229|280=5
3=884|4=884|5=MBREFUSDCMR|24=1|270=252304|280=5

Каждое значение перед знаком равенства представляет идентификатор соответствующего значения.Теперь я хотел бы подготовить таблицу для дальнейшего анализа.Первая строка должна содержать идентификаторы и ниже их значений.В трех строках имеется неодинаковое количество идентификаторов, которые необходимо учитывать.Недостающие значения должны быть заполнены строкой «NA».Таким образом, это должно выглядеть следующим образом:

3|4|5|24|12|10|25|824|387|248|270|280
884|884|MBREFUSDCMR|NA|NA|NA|113500|20120229|4.15|TLD|NA|5
884|884|MBREFUSDCMR|1|0|0|113500|20120229|NA|NA|NA|5
884|884|MBREFUSDCMR|1|NA|NA|NA|NA|NA|NA|252304|5

@ DVK

Мой подход состоял в том, чтобы сначала получить все переменные.Это будет заголовок / первая строка таблицы.Например,

my @data_dirty = <STDIN>;
chomp(@data_dirty);

## get the columns names
my ( @tmp, @var );
foreach my $j (@data_dirty) {
    foreach my $i (split /\|/, $j) {
    $i =~ s/\[.*\]//g;
    $i =~ s/\s+//g;
    $i =~ s/(.*)=.*/$1/g;
    push(@tmp, $i);
    }
}
@var = uniq @tmp;

После этого я могу проверить каждую строку, существует ли переменная в @var, если да, записать соответствующее значение, в противном случае написать "NA".Однако у меня были некоторые проблемы с проверками и правильным хранением данных, так что после этого результат выглядел так, как нужно.

1 Ответ

2 голосов
/ 03 марта 2012

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

Здесь необходимо загрузить данные, и все идентификаторы должны быть известны априори, прежде чем будет напечатана какая-либо таблица.

Пример ниже не упорядочивает столбцы по последовательности их появления (оставлено в качестве упражнения для читателя):

use strict;
use warnings;

my ( $data, $headers ) = load_data( 'tabular_data.txt' );

print_tabular( $data, $headers );

sub load_data {

    my ( $file ) = @_;

    open my $fh, '<', $file or die $!;

    my ( @records, %fields );
    while ( my $line = <$fh> ) {

        chomp $line;

        my @columns = split /\|/, $line;               # Get columns
        my %entries = map { split /=/, $_ } @columns;  # Populate record,
                                                       # keys = fields
        push @records, \%entries;                      # Add to data collection

        $fields{$_}++ for keys %entries;               # Detect new headers
    }

    close $fh;

    return ( \@records, [ keys %fields ] );
}

sub print_tabular {

    my ( $data, $headers ) = @_;

    pretty_print( @$headers );

    for my $record ( @$data ) {
        my @values = map { exists $record->{$_}  # exists check needed...
                             ? $record->{$_}     # ... otherwise header '0'
                             : 'NA'              # ... would always print 'NA'
                         } @$headers;
        pretty_print( @values );
    }
}

sub pretty_print { print join( '|', @_ ), "\n" }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...