Как я могу использовать Perl для извлечения определенного столбца из файла, разделенного табуляцией? - PullRequest
0 голосов
/ 17 августа 2011

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

Код выглядит следующим образом:

#!/usr/bin/perl
open (DATA, "<test1.txt") or die ("Unable to open file");
use strict; use warnings;
my $search_string = "Ball";
while ( my $row = <DATA> ) {

    last unless $row =~ /\S/;
    chomp $row;
    my @cells = split /\t/, $row;

    if ($cells[0] =~/$search_string/){
        print $cells[0];
    }
}

мой файл тестовых данных выглядит так

Camera Make     Camera Model    Text    Ball    Swing
a       b       c       d       e
f       g       h       i       j
k       l       m       n       o

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

Так как мне найти, скажем, "Ball" и вернуть его "d i n"

Ответы [ 4 ]

2 голосов
/ 17 августа 2011

Попробуйте это:

use strict;
use warnings;
use Data::Dumper;
use List::MoreUtils qw<first_index>;

my $column = first_index { $_ eq 'Ball' } split /\t/, <DATA>;
say Data::Dumper->Dump( [ $column ], [ '*column' ] );
my @balls  = map { [split /\t/]->[$column] } <DATA>;
say Data::Dumper->Dump( [ \@balls ], [ '*balls' ] );
__DATA__
Camera Make Camera Model    Text    Ball    Swing
a   b   c   d   e
f   g   h   i   j
k   l   m   n   o

Вам, скорее всего, придется изменить дескриптор с DATA на какой-то файл, который вы open -ed.

open( my $in, '<', '/path/to/data.file' ) 
    or die "Could not open file: $!"
    ;

А затем заменить <DATA> на <$in>.

2 голосов
/ 17 августа 2011

Причина, по которой вы не получаете никаких ошибок, заключается в том, что ваша программа делает именно то, что вы ей сказали (выведите все значения первого столбца, которые содержат строку «Ball»). Поскольку ни одна из ячеек в первом столбце не содержит эту строку, ваша программа ничего не печатает.

Ваша проблема не в вашем Perl (он может использовать незначительные стилистические улучшения - в частности, вы используете устаревшую форму open() - но в основном это нормально), это с вашим алгоритмом .

СОВЕТ: ваша первая задача в алгоритме должна найти, КАКОЙ столбец (по номеру) является столбцом "Ball".

0 голосов
/ 17 августа 2011

Вы можете использовать Text :: CSV_XS , чтобы очень удобно извлечь данные для вас.Это может быть излишним для ваших ограниченных данных, но это очень надежное решение.

Здесь я просто использую тег DATA для хранения данных, но если вы предпочитаете, вы можете заменить этос файловым дескриптором, таким как open my $fh, '<', 'text1.txt'; и изменить *DATA на $fh.

Выход:

d i n

Код:

use warnings;
use strict;
use Text::CSV_XS;
use autodie;

my $csv = Text::CSV_XS->new( { sep_char => "\t" } );
my @list;
$csv->column_names ($csv->getline (*DATA));
while ( my $hr = $csv->getline_hr(*DATA) ) {
    push @list, $hr->{'Ball'};
}

print "@list\n";
__DATA__
Camera Make Camera Model    Text    Ball    Swing
a   b   c   d   e
f   g   h   i   j
k   l   m   n   o

ETA: Если вы собираетесь вырезать и вставить, чтобы попробовать, убедитесь, что вкладки в данных переносятся.

0 голосов
/ 17 августа 2011

Попробуйте вместо этого:

#!/usr/bin/perl
use strict;
use warnings;

open (DATA, "<test1.txt") or die ("Unable to open file");
my $search_string = "Ball";

my $header = <DATA>;
my @header_titles = split /\t/, $header;
my $extract_col = 0;

for my $header_line (@header_titles) {
  last if $header_line =~ m/$search_string/;
  $extract_col++;
}

print "Extracting column $extract_col\n";

while ( my $row = <DATA> ) {
  last unless $row =~ /\S/;
  chomp $row;
  my @cells = split /\t/, $row;
  print "$cells[$extract_col] ";
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...