Как мне обработать / сохранить несколько строк в одном поле, прочитанном из файла в perl? - PullRequest
3 голосов
/ 20 мая 2011

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

Пример файла data.txt:

ID|Title|Description|Date
1|Example 1|Example Description|10/11/2011
2|Example 2|A long example description
Which contains
a bunch of newlines|10/12/2011
3|Example 3|Short description|10/13/2011

Текущий (неработающий) скрипт Perl (пример):

#!/usr/bin/perl -w
use strict;

open (MYFILE, 'data.txt');
while (<MYFILE>) {
    chomp;
    my ($id, $title, $description, $date) = split(/\|/);

    if ($id ne 'ID') {
        # processing certain fields (...)

        # insert into the database (example)
        $sqlInsert->execute($id, $title, $description, $date);
    }
}
close (MYFILE);

Как видно из примера, в случае идентификатора 2 он разбит на несколько строк, что приводит к ошибкам при попытке обратиться к этим неопределенным переменным. Как бы вы сгруппировали их в правильное поле?

Заранее спасибо! (Надеюсь, вопрос был достаточно ясным, трудно определить заголовок)

Ответы [ 3 ]

5 голосов
/ 20 мая 2011

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

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

open (MYFILE, '<', 'data.txt');
while (<MYFILE>) {
    # Continue reading while line incomplete:
    while (tr/|// < 3) {
        my $next = <MYFILE>;
        die "Incomplete line at end" unless defined $next;
        $_ .= $next;
    }

    # Remaining code unchanged:
    chomp;
    my ($id, $title, $description, $date) = split(/\|/);

    if ($id ne 'ID') {
        # processing certain fields (...)

        # insert into the database (example)
        $sqlInsert->execute($id, $title, $description, $date);
    }
}
close (MYFILE);
0 голосов
/ 20 мая 2011

Если бы вы могли изменить свой файл data.txt, чтобы включить разделитель каналов в качестве последнего символа в каждой строке / записи, вы могли бы выплескивать весь файл, разбивая его непосредственно на необработанные поля. Этот код будет делать то, что вы хотите:

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

my @fields;
{
  $/ = "|";
  open (MYFILE, 'C:/data.txt') or die "$!";
  @fields = <MYFILE>;
  close (MYFILE);

  for(my $i = 0; $i < scalar(@fields); $i = $i + 4) {
    my $id = $fields[$i];
    my $title = $fields[$i+1];
    my $description = $fields[$i+2];
    my $date = $fields[$i+3];
    if ($id =~ m/^\d+$/) {
        # processing certain fields (...)

        # insert into the database (example)
    }
  }
}
0 голосов
/ 20 мая 2011

Читайте следующую строку, пока количество полей не будет тем, что вам нужно.Примерно так (я не проверял этот код):

my @fields = split(/\|/);
unless ($#fields == 3) { # Repeat untill we get 4 fields in array

  <MYFILE>; # Read next line      
  chomp;

  # Split line
  my @add_fields = split(/\|/); 

  # Concatenate last element of first line with first element of the current line
  $fields[$#fields] = $fields[$#fields] . $add_fields[0]; 

  # Concatenate remaining array part
  push(@fields, @add_fields[1,$#add_fields]);

}
...