#perl #csv #text
#perl #csv #текст
Вопрос:
У меня есть простой csv-файл, в котором есть данные, которые я хочу извлечь из записи в новый файл.
Я хочу написать скрипт, который читает файл, считывает каждую строку, затем разбивает и структурирует столбцы в другом порядке, и если строка в .csv содержит ‘xxx’ — не выводите строку в выходной файл.
Мне уже удалось прочитать файл и создать дополнительный файл, однако я новичок в Perl и все еще пытаюсь разобраться с командами, ниже приведен тестовый скрипт, который я написал, чтобы освоиться с Perl, и мне было интересно, могу ли я изменить это на то, что мне нужно?-
open (FILE, "c1.csv") || die "couldn't open the file!";
open (F1, ">c2.csv") || die "couldn't open the file!";
#print "startn";
sub trim($);
sub trim($)
{
my $string = shift;
$string =~ s/^s //;
$string =~ s/s $//;
return $string;
}
$a = 0;
$b = 0;
while ($line=<FILE>)
{
chop($line);
if ($line =~ /xxx/)
{
$addr = $line;
$post = substr($line, length($line)-18,8);
}
$a = $a 1;
}
print $b;
print " endn";
Любая помощь приветствуется.
Комментарии:
1. Я подумал, что дам вам пару указаний по стилю, надеюсь, вы не возражаете. 0. Поместите
use strict;
иuse warnings;
в начало всех ваших скриптов. Вам придется объявлять переменные с помощьюmy
, но это сэкономит вам время отладки в долгосрочной перспективе — примерmy $foo = bar();
1. В perl нет необходимости предварительно раскрывать ваши подпрограммы — за более чем десятилетие интенсивного использования Perl мне никогда не требовалась эта функция. 2. В общем, не используйте прототипы на своих дочерних устройствах, они работают не так, как на других языках. Это всего лишь подсказки компилятора, и их можно легко обойти.2. Больше указателей стиля. 3. Переменные
$a
и$b
являются специальными переменными, используемымиsort
. Лучше не использовать их где-либо еще. Это может быть безопасно, если вы убедитесь, что они имеют лексическую область видимости, но, в общем, я их избегаю. 4. Дескрипторы файлов, подобныеFILE
, являются глобальными переменными, и их лучше всего заменить лексическими дескрипторами. 5. Open имеет форму с 3 аргументами и форму с 2 аргументами. Версия с двумя аргументами сохранена для обратной совместимости, но у нее есть некоторые проблемы. Вместо этого используйте форму аргумента 3. Пример современного 3-аргументного открытого:open my $fh, '>', $path_to_some_file or die "Didn't work: $!n";
.3. Большинство этих проблем с вашим кодом связаны с устаревшими или запутанными документами. К счастью, существуют источники более современного использования Perl. » Эффективное программирование на Perl» Брайана Д. Фоя и » Современный Perl » Хроматика — пара превосходных книг. Современный Perl даже доступен для бесплатного скачивания: onyxneon.com/books/modern_perl/index.html
Ответ №1:
Для работы с CSV-файлами лучше использовать один из доступных модулей в CPAN. Мне нравится текст::CSV:
use Text::CSV;
my $csv = Text::CSV->new ({ binary => 1, empty_is_undef => 1 }) or die "Cannot use CSV: ".Text::CSV->error_diag ();
open my $fh, "<", 'c1.csv' or die "ERROR: $!";
$csv->column_names('field1', 'field2');
while ( my $l = $csv->getline_hr($fh)) {
next if ($l->{'field1'} =~ /xxx/);
printf "Field1: %s Field2: %sn", $l->{'field1'}, $l->{'field2'}
}
close $fh;
Комментарии:
1. Спасибо за ввод, но он выдает ошибку «Не удается найти текст / CSV.pm в @INC <@INC содержит: C:/Perl/site/lib C:/Perl/Lib .>
2. Я полностью согласен с PacoRG; Text::CSV — правильный путь здесь.
3. Ламбо: сначала вам нужно установить
Text::CSV
модуль. Попробуйте установить его из PPM, следуя приведенным здесь инструкциям: docs.activestate.com/activeperl/5.10/faq/ActivePerl-faq2.html4. ах, я вижу, что мне этого не хватало! Спасибо за это, я его установлю.
5. Если Text::CSV не установлен в вашей системе и у вас нет времени на его установку, альтернативой может быть использование модуля Text ::ParseWords, который поставляется как часть стандартной установки Perl и, следовательно, уже будет установлен.
Ответ №2:
Если вам нужно сделать это только один раз, чтобы программа не понадобилась позже, вы можете сделать это с помощью oneliner:
perl -F, -lane 'next if /xxx/; @n=map { s/(^s*|s*$)//g;$_ } @F; print join(",", (map{$n[$_]} qw(2 0 1)));'
Разбивка:
perl -F, -lane
^^^ ^ <- split lines at ',' and store fields into array @F
next if /xxx/; #skip lines what contain xxx
@n=map { s/(^s*|s*$)//g;$_ } @F;
#trim spaces from the beginning and end of each field
#and store the result into new array @n
print join(",", (map{$n[$_]} qw(2 0 1)));
#recombine array @n into new order - here 2 0 1
#join them with comma
#print
Конечно, для повторного использования или в более крупном проекте вам следует использовать какой-нибудь модуль CPAN. И в приведенном выше oneliner тоже много оговорок.