Использование perl для разбора файла и вставки определенных значений в базу данных - PullRequest
3 голосов
/ 22 апреля 2010

Отказ от ответственности: я новичок в написании сценариев на Perl, это отчасти учебное упражнение (но все же проект для работы). Кроме того, я гораздо лучше разбираюсь в сценариях оболочки, так что мои примеры, скорее всего, будут отформатированы в соответствии с этим мышлением (но я хотел бы создать их в perl). Заранее извините за многословие, я хочу убедиться, что я хотя бы немного ясен в изложении своей точки зрения

У меня есть текстовый файл (справочное руководство), который представляет собой документ Word, преобразованный в текст, затем поменянный из Windows в формат UNIX в Notepad ++. Файл одинаков в том смысле, что каждый раздел файла имеет одинаковые поля / formatting / tables.

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

Итак, я хочу захватить каждый раздел, выполнив что-то вроде:
sed -n '/job_name_1_regex/,/job_name_2_regex/' file.txt - как это будет отформатировано в скрипте perl?
(захватите секцию полностью, затем разбейте ее дальше оттуда)

Чтобы прочитать файл в сценарии, у меня есть open FORMAT_FILE, 'test_format.txt';, а затем использовать foreach $line (<FORMAT_FILE>) для разбора файла строка за строкой. - есть ли лучший способ?

Моя следующая проблема заключается в том, что, поскольку я преобразовал слово doc с таблицами, которое выглядит следующим образом:

<strong> Table Heading 1      Table Heading 2</strong>
Heading 1/Value 1    Heading 2/Value 1
Heading 1/Value 2    Heading 2/Value 2

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

<strong>Table Heading 1 
Table Heading 2</strong><br>Heading 1/Value 1<br>Heading 1/Value 2<br>Heading 2/Value 1<br>Heading 2/Value 2

Итак, я хочу, чтобы в качестве имени столбца было указано «Заголовок 1» и «Заголовок 2», а затем поместил соответствующие значения. Я просто не уверен, как получить значения по отношению к заголовку из текстового файла. Значения заголовка 1 всегда будут номером строки заголовка 1 плюс 2 (заголовок 1, заголовок 2, значения для заголовка 1). Я знаю, что это можно сделать в awk / sed довольно легко, но я не знаю, как решить эту проблему внутри сценария perl.

--- EDIT ---
Для этого я думал о создании массива что-то вроде:

my @heading1 = ($value1, $value2, etc.)
my @heading2 = ($value1, $value2, etc.)

Мне просто нужно иметь возможность связать правильные значения и заголовки вместе. Таким образом, заголовок 1 = строка после заголовка 2 (где начинаются значения). Как сказать (в оболочке):

x=$(grep -n "Heading 1" file.txt | cut -d":" -f1) #gets the line that "Heading 1" is on in the file
(( x = x+2 )) #adds 2 to the line (where the values will start)
#print values from file.txt from the line where they start to the
#last one (I'll figure that out at some point before this)
sed -n "$x,$last_line_of_values p" file.txt

На данный момент это вместе взломано, чтобы попытаться прояснить, что я хочу сделать ... дайте мне знать, если это немного прояснится ...
--- / EDIT ---

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

Извините, если это немного рассеянно ... все еще не полностью сформировано в моей голове.

Ответы [ 2 ]

3 голосов
/ 22 апреля 2010

http://perlmeme.org/tutorials/connect_to_db.html

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

my $driver = "mysql";   # Database driver type
my $database = "test";  # Database name
my $user = "";          # Database user name
my $password = "";      # Database user password

my $dbh = DBI->connect(
    "DBI:$driver:$database",
    $user, $password,
    {
        RaiseError => 1,
        PrintError => 1,
    }
) or die $DBI::errstr;

my $sth = $dbh->prepare("
        INSERT INTO test 
                    (col1, col2)
             VALUES (?, ?)
    ") or die $dbh->errstr;

my $intable = 0;
open my $file, "file.txt" or die "can't open file $!";
while (<$file>)  {
  if (/job_name_1_regex/../job_name_2_regex/) { # job 1 section
    $intable = 1 if /Table Heading 1/; # table start
    if ($intable) {
      my $next_line = <$file>; # heading 2 line
      chomp; chomp $next_line;
      $sth->execute($_, $next_line) or die $dbh->errstr;
    }
  }
}
close $file or die "can't close file $!";
$dbh->disconnect;
2 голосов
/ 22 апреля 2010

Несколько вещей в этом посте ... Во-первых, основные «лучшие практики»:

  1. использует современный Perl.запустите ваши скрипты с

    use strict; use warnings;

  2. не используйте глобальные файловые дескрипторы, используйте лексические файловые дескрипторы (объявляйте их в переменной).1014 *

    всегда проверять «открыто» для возвращаемых значений.

    open my $file, "/some/file" or die "can't open file : $!"

Далее о сопоставлении с образцом: я совсем не понимаю ваш пример, но, полагаю, вы хотите что-то вроде:

foreach my $line ( <$file> ) {
    if ( $line =~ /regexp1/) { 
    # do something...
    }

}

Edit: о таблице, я полагаю, лучше всего построить два массива, по одному для каждого столбца.Если я правильно понимаю при чтении файла, вам нужно разбить строку и поместить одну часть в массив @ col1, а вторую часть в массив @ col2.Простой и понятный способ - использовать две временные переменные:

my ( $val1, $val2 ) = split /\s+/, $line;
push @col1, $val1;
push @col2, $val2;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...