Модераторы: ginnie, korob2001
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Разбить файл на части по вхождению строки, получение частей файла 
:(
    Опции темы
AndreRoux
  Дата 30.7.2012, 22:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 30.7.2012

Репутация: нет
Всего: нет



Добрый вечер всем.

При изучении Perl столкнулся со следующей проблемой:
Есть файл x в него постоянно добавляется информация в таком виде:

From [email protected]
......
......

From [email protected]
......
......

и т.д.

Моя задача разбить этот файл на части, то есть чтобы каждая часть файла выглядела так:

From [email protected]
......
......

Но при разделении файла функцией split() выводятся только вхождения шаблона, я этому не удивляюсь ведь так и должно быть, но я уже 12 часов ломаю голову как разбить его на части, файл очень большой до 10Гб. Прошу помощи у коллег  smile

На данный момент код у меня записывает только строки From... а остальное складывает водну кучу(
Код

#!/usr/bin/perl

use strict;

open my $mailBoxFile, "< sss.mailbox";

my $autor    = undef;
my $message = undef;
my %mailBox = ();
my $count    = 0;

while (<$mailBoxFile>) {
    if (/^From (\w+)@(\w+).[a-z]+.*(\d+)$/i) {
        chomp;
        $autor = $_;
        $count++;
        next;
    }
    unless (/^From (\w+)@(\w+).[a-z]+.*(\d+)$/i) {
        $message .= $_;
    } else {
        next;
    }
    $mailBox{$autor} = $message . "\n";
}

close $mailBoxFile;

print $count . "\n";

foreach (sort keys %mailBox) {
    print "$_ $mailBox{$_}\n";
}

Пожалуйста помогите решить проблему, некак не могу додуматься как это сделать. Из тем про парсинг примеры к сожалению не помогли

Это сообщение отредактировал(а) AndreRoux - 31.7.2012, 00:55
PM MAIL   Вверх
Pfailed
Дата 31.7.2012, 08:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 933
Регистрация: 19.7.2009

Репутация: 2
Всего: 39



Может быть так?
Код

while (<$mailBoxFile>) {
    if (/^From (\w+)@(\w+).[a-z]+.*(\d+)$/i) {
        chomp;
        $autor = $_;
        $count++;
        next;
    }
    
    $mailBox{$autor} .= $_;
}




--------------------
PM MAIL   Вверх
TP@MB@Y
Дата 31.7.2012, 08:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 370
Регистрация: 18.12.2004
Где: Москва

Репутация: нет
Всего: 4



Нужны уточнения:

1) "Файл нужно разбить на части"
т.е. нужно создать много других файлов?

2) Что должно храниться в этих файлах?
Например, исходный файл состоит только из этих строчек:

Код

From [email protected]
...
...
From [email protected]
...
...
From [email protected]
...
...


Что вы хотите получить на выходе?

Это сообщение отредактировал(а) TP@MB@Y - 31.7.2012, 08:58
PM   Вверх
AndreRoux
Дата 31.7.2012, 10:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 30.7.2012

Репутация: нет
Всего: нет



Pfailed, большое вам спасибо вы помогли мне продвинуться дальше)

TP@MB@Y, да именно так, на выходе нужны файлы вот такого типа :
From [email protected]
......
т.е. разбивать большой файл на маленькие от вхождения искомой строки до следующего вхождения искомой строки (т.е. следующее вхождение это уже файл2)

Сейчас у меня код вот такой, да вроде бы все правильно но Perl не находит почему то совпадения в файле хоть они и есть, кстати когда я создаю тестовый файл с парочкой заголовков и сообщений совпадения находятся и создаются файлы для каждого сообщения, но когда я меняю адрес файла на настоящий совпадений как небывало(
Код

#!/usr/bin/perl

use strict;

my $header    = undef;
my $autor    = undef;
my $message    = undef;
my %email    = undef;
my $count    = 0;

open my $mailBoxFile, "< ./unix.mailbox";

while (<$mailBoxFile>) {
    if (m/^From\s+(\w+)@(\w+).([a-z]+)/i) {
        $header = $_;
        $count++;
        next;
    }
    $email{$header} .= $_;
}

close $mailBoxFile;

foreach (sort keys %email) {
    if (m/^From\s+(\w+)@(\w+).([a-z]+)(.*\s+)(\d+)$/i) {
        $autor = "$1\@$2.$3";
    }
    open my $fileAutorsMessage, "> ./messages/$autor.mailbox";
    print $fileAutorsMessage "$_$email{$_}";
    close $fileAutorsMessage;
}


Добавлено через 8 минут и 12 секунд
В тестовом шаблоне вид вот такой:
Код

From [email protected]  Fri Oct  1 14:42:19 2010
Привет как дела ?
Я тут кое что смотрю...

From [email protected]  Sat Aug 28 12:43:39 2010
Нормуль все

From [email protected]  Sun Mar 21 08:39:48 2010
Ага
А кстати
зацени


В настоящем (большой файл) следующий (выведено два сообщения - разделить как и 1-м строка From...):
Код

From [email protected]  Fri Oct  1 14:42:19 2010
Return-Path: <[email protected]>
Received: from compute2.internal (compute2.nyi.mail.srv.osa [10.202.2.42])
     by store114m.internal (Cyrus v2.4.0-git-fastmail-6103) with LMTPA;
     Fri, 01 Oct 2010 06:42:19 -0400
X-Sieve: CMU Sieve 2.3
X-Spam-charsets: html='iso-8859-1'
X-Resolved-to: [email protected]
X-Delivered-to: [email protected]
X-Mail-from: [email protected]
Received: from mx2.messagingengine.com ([10.202.2.201])
  by compute2.internal (LMTPProxy); Fri, 01 Oct 2010 06:42:19 -0400
Received: from jav-e77efe20567 (unknown [197.224.102.106])
    by mx2.messagingengine.com (Postfix) with SMTP id BF886B0000F
    for <[email protected]>; Fri,  1 Oct 2010 06:42:17 -0400 (EDT)
From: <[email protected]>
To: [email protected]
Subject: CILIAS LOWEST PRICE!!!
Date: Fri, 1 Oct 2010 14:38:44 +0400
MIME-Version: 1.0
Content-Type: text/html; charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
X-Truedomain-Domain: nkgreensold.org
X-Truedomain-SPF: None
X-Truedomain-DKIM: None
X-Truedomain: Neutral
Message-ID: <[email protected]>

<br>
<br>
<a href="http://nkgreensold.org/?cid=sale555_3009">



http://nkgreensold.org



</a>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<!-- Message-ID: 47328-28811-66607 -->
<br>


From [email protected]  Sat Aug 28 12:43:39 2010
Return-Path: <[email protected]>
Received: from compute3.internal (compute3.internal [10.202.2.43])
     by store114m.internal (Cyrus v2.4.0-git-fastmail-5781) with LMTPA;
     Sat, 28 Aug 2010 04:43:39 -0400
X-Sieve: CMU Sieve 2.3
X-Spam-charsets: subject='windows-1251', html='windows-1251'
X-Resolved-to: [email protected]
X-Delivered-to: [email protected]
X-Mail-from: [email protected]
Received: from mx2.messagingengine.com ([10.202.2.201])
  by compute3.internal (LMTPProxy); Sat, 28 Aug 2010 04:43:39 -0400
Received: from ns11.wistee.fr (dns-ns11.wistee.fr [94.124.84.11])
    (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))
    (No client certificate requested)
    by mx2.messagingengine.com (Postfix) with ESMTPS id 17735B000BC
    for <[email protected]>; Sat, 28 Aug 2010 04:43:39 -0400 (EDT)
Received: from 94-248-14-53.dynamic.peoplenet.ua ([94.248.14.53] helo=sk-823d9484f049)
    by ns11.wistee.fr with esmtpa (Exim 4.71)
    (envelope-from <[email protected]>)
    id 1OpH08-0000Lr-Bi; Sat, 28 Aug 2010 10:43:00 +0200
Message-ID: <6B252F83B0314304AA2B7110C4437CB9@sk-823d9484f049>
Reply-To: "Admin_loveplanet" <[email protected]>
From: "Admin_loveplanet" <[email protected]>
Subject: =?windows-1251?B?z+7n5PDg4uv/5ewg4uDx?=
Date: Sat, 28 Aug 2010 11:42:34 +0300
Organization: =?windows-1251?B?zs7OICJsb3ZlcGxhbmV0Ig==?=
MIME-Version: 1.0
Content-Type: text/html;
    charset="windows-1251"
Content-Transfer-Encoding: 7bit
X-Priority: 3
X-MSMail-Priority: Normal
X-Mailer: Microsoft Windows Mail 6.0.6001.18000
X-MimeOLE: Produced By Microsoft MimeOLE V6.0.6001.18049
X-Truedomain-Domain: gmail.com
X-Truedomain-SPF: Neutral (mx2: 94.124.84.11 is neither permitted nor denied by domain of gmail.com)
X-Truedomain-DKIM: None
X-Truedomain: Neutral

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=windows-1251">
<META content="MSHTML 6.00.6001.18099" name=GENERATOR>
</HEAD>
<BODY bgcolor="#ffffff" leftmargin=5 topmargin=5 rightmargin=5 bottommargin=5>
<font size=2 color="#000000" face="Arial">
<div>Найти друга по переписке или завести виртуальный роман ...,http://superpopkaany.narod.ru/,Раз строка</div>
</font>
</BODY></HTML>

PM MAIL   Вверх
TP@MB@Y
Дата 31.7.2012, 11:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 370
Регистрация: 18.12.2004
Где: Москва

Репутация: нет
Всего: 4



Уважаемый AndreRoux

если вы хотите помощи, дайте ответ на мой вопрос:

Цитата(TP@MB@Y @  31.7.2012,  08:57 Найти цитируемый пост)
 Что должно храниться в этих файлах?
Например, исходный файл состоит только из этих строчек:

From [email protected]
...
...
From [email protected]
...
...
From [email protected]
...
...


Что вы хотите получить на выходе?


PM   Вверх
AndreRoux
Дата 31.7.2012, 11:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 30.7.2012

Репутация: нет
Всего: нет



TP@MB@YPfailed, большое вам спасибо за помощь! smile 

Проблему решил так:
Код

#!/usr/bin/perl

use strict;

my $header    = undef;
my $autor    = undef;
my %email    = undef;
my $count    = 0;

open my $mailBoxFile, "< ./unix.mailbox" or die("Can not open file");

while (<$mailBoxFile>) {
    if (m/^From\s+(.+)@(.+).([a-z]+).*$/) {
        $header = $_;
        $count++;
        next;
    }
    $email{$header} .= $_;
}

close $mailBoxFile;

foreach (sort keys %email) {
    if (m/^From\s+(.+)@(.+).([a-z]+).*$/) {
        $autor = "$1\@$2.$3";
    }
    unless (-e "./messages/$autor.mailbox") {
        open my $fileAutorsMessage, "> ./messages/$autor.mailbox" or die("Can not open file");
        print $fileAutorsMessage "$_$email{$_}";
        close $fileAutorsMessage;
    } else {
        open my $fileAutorsMessage, "> ./messages/$autor.mailbox" or die("Can not open file");
        print $fileAutorsMessage "$_$email{$_}";
        close $fileAutorsMessage;
    }
}


PM MAIL   Вверх
TP@MB@Y
Дата 31.7.2012, 11:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 370
Регистрация: 18.12.2004
Где: Москва

Репутация: нет
Всего: 4



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

изначально у вас не было четкого алгоритма, что и вызвало кучу вопросов.

ну ладно, вы говорите, что разобрались и приводите тут свой код на перле.

я так понял, вы 
1) пробегаетесь по 10-ти гиговому файлу и собираете его содержимое (с группировкой по строчке с мейлом) в хэш %email....
2) вы пробегаетесь циклом по отсортированному списку строчек с мейлом, опять парсите регуляркой строчку, выдирая имено мейл
3.1) если файл с соответствующим именем существует - открываете его на запись и пишете туда все что собрали по соотвествующему мейлу
3.2) если файл с соответствующим именем не существует - открываете его на запись и пишете туда все что собрали по соотвествующему мейлу

жирным я выделил моменты, которые мне показались не очень удачными
также не нашел отличий между пунктами 3.1 и 3.2
PM   Вверх
AndreRoux
Дата 31.7.2012, 12:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 30.7.2012

Репутация: нет
Всего: нет



3.1, 3.2 уже вырезал из программы. Ну файл не всегда такой большой он может быть и 50Кб
Ну что поделаешь, до этого была только теория из книжек кэмеэл и ламы с минимумом примеров, а тут сразу свалилась такая задача)
Опыта еще нет. Если вы мне объясните некоторые принципы и ходы для этого примера да и вообще на будущее я вам буду очень благодарен    smile 

Это сообщение отредактировал(а) AndreRoux - 31.7.2012, 12:42
PM MAIL   Вверх
TP@MB@Y
Дата 31.7.2012, 15:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 370
Регистрация: 18.12.2004
Где: Москва

Репутация: нет
Всего: 4



Возможности проверить код нет, но суть, я думаю понятна:

Код

#!/usr/bin/perl

use strict;
use warnings;

sub save_buf {
    my ($email, $buf) = @_;
    open F, ">> ./messages/$email.mailbox" or die("Can not open file");
    print F $buf;
    close F;
}

open my $mailBoxFile, "< ./unix.mailbox" or die("Can not open file");

my $prev_email = undef;
my $buf = "";
while (<$mailBoxFile>) {
    if (m/^From\s+(.+)@(.+).([a-z]+).*$/) { # регулярка плохая! нужно улучшить!
        my $email = "$1\@$2.$3";
        if ($email ne $prev_email) {
             save_buf($prev_email, $buf);
             $buf = "";
             $prev_email = $email;
        }
        next;
    }
    $buf .= $_;
}
save_buf($prev_email, $buf);

close $mailBoxFile;

PM   Вверх
arto
Дата 1.8.2012, 09:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1495
Регистрация: 31.10.2004

Репутация: 1
Всего: 40



perl -lne 'BEGIN{ $/ = "\nFrom "; } $. == 1 && s#^From ##; my $a = (split "\\s+",$_,2)[0] or next; open F, ">> $a" and print F "From $_"' $MAIL
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl: Системное программирование"
korob2001
sharq
  • В этом разделе обсуждаются вопросы относящиеся только к системному программированию на Perl
  • Если ваш вопрос не относится к системному или CGI программированию, задавайте его в общем разделе
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: Системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.1438 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.