Как я могу отфильтровать определенный столбец из файла CSV в Perl? - PullRequest
0 голосов
/ 09 января 2009

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

Большое спасибо за помощь.

ура, Ниль

Ответы [ 10 ]

20 голосов
/ 09 января 2009

Посмотрите Text :: CSV (или Text :: CSV_XS ), чтобы проанализировать файлы CSV в Perl. Он доступен на CPAN или вы можете получить его через менеджер пакетов, если вы используете Linux или другую Unix-подобную ОС. В Ubuntu пакет называется libtext-csv-perl.

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

6 голосов
/ 09 января 2009

CSV - это плохо определенный, сложный формат (странные проблемы с кавычками, запятыми и пробелами). Ищите библиотеку , которая может обрабатывать нюансы для вас, а также предоставляет вам такие удобства, как индексация по именам столбцов.

Конечно, если вы просто хотите разделить текстовый файл запятыми, ищите решение @ Pax.

5 голосов
/ 09 января 2009

Используйте разделение, чтобы отделить строку, а затем вывести нужные (например, каждый второй столбец), создайте следующий файл xx.pl:

while(<STDIN>) {
    chomp;
    @fields = split (",",$_);
    print "$fields[1],$fields[3],$fields[5],$fields[7],$fields[9]\n"
}

затем выполните:

$ echo 1,2,3,4,5,6,7,8,9,10 | perl xx.pl
2,4,6,8,10
3 голосов
/ 09 января 2009

Если вы говорите о файлах CSV в Windows (например, сгенерированных из Excel), вам нужно быть осторожным, чтобы позаботиться о полях, которые содержат запятую, но заключены в кавычки.

В этом случае простое split не будет работать.

2 голосов
/ 30 января 2009

Вы можете использовать некоторые встроенные в Perl опции времени выполнения, чтобы сделать это в командной строке:

$ echo "1,2,3,4,5" | perl -a -F, -n -e 'print join(q{,}, $F[0], $F[3]).qq{\n}' 1,4

Выше будет -a (утосплит) с использованием -F (ield) запятой. Затем он объединит интересующие вас поля и выведет их обратно (с разделителем строк). Это предполагает простые данные без вложенной запятой. Я делал это с непечатаемым разделителем полей (\ x1d), так что это не проблема для меня.

Подробнее см. http://perldoc.perl.org/perlrun.html#Command-Switches.

2 голосов
/ 09 января 2009

Кроме того, вы можете использовать Text :: ParseWords , который находится в стандартной библиотеке. Добавить

use Text::ParseWords;

к началу примера Pax выше, а затем подставьте

  my @fields = parse_line(q{,}, 0, $_);

для раскола.

1 голос
/ 17 января 2009

Пошел искать, не нашел хорошую CSV-совместимую программу фильтрации, которая была бы гибкой, чтобы быть полезной, чем просто один из, поэтому я написал одну. Наслаждайтесь.

Базовое использование:

bash $ csvfilter [-r ] * [-quote]

#!/usr/bin/perl

use strict;
use warnings;
use Getopt::Long;

use Text::CSV;

my $always_quote=0;

my @remove;
if ( ! GetOptions('remove:s'=> \@remove,
          'quote-always'=>sub {$always_quote=1;}) ) {
   die "$0:invalid option (use --remove  [--quote-always])";
}

my @cols2remove;

sub filter(@)
{
   my @fields=@_;
   my @r;
   my $i=0;
   for my $c (@cols2remove) {
       my $p;
       #if ( $i  $i ) {
       push(@r, splice(@fields, $i));
   }
   return @r;
}

# create just one if these
my $csvOut=new Text::CSV({always_quote=>$always_quote});

sub printLine(@)
{
    my @fields=@_;
    my $combined=$csvOut->combine(filter(@fields));
    my $str=$csvOut->string();
    if ( length($str) ) {
     print "$str\n";
    }
}

my $csv = Text::CSV->new();

my $od;
open($od, "| cat") || die "output:$!";
while () {
    $csv->parse($_);
    if ( $. == 1 ) {
    my $failures=0;
    my @cols=$csv->fields;
    for my $rm (@remove) {
        for (my $c=0; $c$b} @cols2remove);
    }
    printLine($csv->fields);
}

exit(0);
\
0 голосов
/ 09 января 2009

Мой личный любимый способ сделать CSV - использовать модуль AnyData . Кажется, все довольно просто, и удаление именованного столбца может быть сделано довольно легко. Посмотрите на CPAN .

0 голосов
/ 09 января 2009

В дополнение к тому, что люди здесь говорили об обработке файлов, разделенных запятыми, я хотел бы отметить, что можно извлечь четные (или нечетные) элементы массива, используя фрагмент массива и / или карту:

@myarray[map { $_ * 2 } (0 .. 4)]

Надеюсь, это поможет.

0 голосов
/ 09 января 2009

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

Команда unix cut может делать то, что вы хотите (и многое другое). Это было переопределено в Perl .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...