Распечатать заголовок CSV с Tie :: Handle :: CSV - PullRequest
6 голосов
/ 13 января 2010

Я написал Perl-скрипт, используя Tie :: Handle :: CSV, чтобы обработать кучу данных в CSV-файле и распечатать только то, что мне нужно, в новый CSV-файл. Прямо сейчас я распечатываю строку заголовка со всеми именами полей, просто жестко закодировав ее так:

print '"TERM", "STUDENT ID", "NAME", ..."'."\n";

Я подозреваю, что это глупый способ сделать это, но я не знаю, как получить доступ к заголовку из объекта Tie :: Handle :: CSV. Он создан так,

my $fh = Tie::Handle::CSV->new($file,header=> 1);

и данные доступны так,

$line -> {'CATALOG_NBR'}

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

Большое спасибо за любую помощь! JA

Ответы [ 4 ]

6 голосов
/ 16 января 2010

Немного опоздал на вечеринку, но я только что выпустил новую версию Tie::Handle::CSV (через несколько часов должен появиться CPAN). Добавлена ​​поддержка метода header(), который возвращает отформатированный заголовок CSV. Использование может выглядеть так:

   my $fh = Tie::Handle::CSV->new( $file, header => 1 );
   print $fh->header;

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

  • danboo
3 голосов
/ 13 января 2010

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

use strict;
use warnings;
use Tie::Handle::CSV;
use Data::Dumper;

my $csv_fh = Tie::Handle::CSV->new('basic.csv', header => 0);
my $header = <$csv_fh>;
close $csv_fh;
print join(',', @$header), "\n";

$csv_fh = Tie::Handle::CSV->new('basic.csv', header => 1);
while (my $csv_line = <$csv_fh>) {
    # $csv_line can be used here
    ...
}
close $csv_fh;
2 голосов
/ 13 января 2010

Согласно документации , похоже, что отключение header => 1 в вашем конструкторе приведет к тому, что он не проанализирует заголовок. Затем вы должны получить имена столбцов заголовка в качестве первого $line, возвращенного из объекта.

Это также означает, что ваши $line будут ссылками на массивы, а не ссылками на хеш, поэтому вам нужно будет печатать позиционные значения с $line->[0], $line->[1] и т. Д. Вместо использования имен заголовков .

Если вы хотите использовать опцию header => 1, вы можете получить хеш-ключи с помощью my @headers = keys %{ $line }. Обратите внимание, что нет никакой гарантии, что ключи будут в каком-либо конкретном порядке, поэтому вам придется найти способ заказать их самостоятельно.

На самом деле я не использовал этот модуль, так что все это предположения, основанные на прочтении документации для опции header.

1 голос
/ 13 января 2010

Спасибо, ребята - я закончил тем, что сделал по существу комбинацию вашего совета. Я открыл два дескриптора файла - второй $ hfh с заголовком => 0, чтобы я мог печатать метки заголовка в правильном порядке, например:

my $fh = Tie::Handle::CSV->new($file,  header => 1);
my $hfh = Tie::Handle::CSV->new($file, header=>0);
my $line = <$hfh>;
my $header;
foreach(@{$line}) {
  $header .= "\"$_\",";
}
print "$header\n";

Еще раз спасибо за вашу помощь!

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