#perl #file-io #performance #processing-efficiency
#perl #file-io #Производительность #эффективность обработки
Вопрос:
У меня есть очень большой файл размером около 300-500 МБ. Сначала мне нужно выполнить поиск String1 в этом файле. Затем выполните поиск String2, начиная с позиции String1. Затем снова выполните поиск String3, начиная с позиции String2. Например,
String1 = "abc"
String2 = "123"
String3 = "opq"
Файл :
def
123
opq
opq
123
opq
abc //come here first
blah blah
123 //come here next
blah
opq //read this finally and print
afg
123
blah blah
123
def
Методы, которым я следовал,
-
Я попробовал читать файл построчно и искать соответствующий шаблон.
Это был очень медленный метод (пришлось ждать несколько минут).
-
Затем я сохранил весь файл в массив и обработал совпадающие строки, чтобы получить последнюю строку.
Это было довольно быстро при поиске, но медленнее при загрузке файла в массив. Потребляемая память также высока.
Существует ли эффективный метод для выполнения такой задачи?
Комментарии:
1. Добавьте свой код к вопросу.
2. На самом деле это небольшой файл. Чтение построчно должно работать нормально
3. вы работаете в среде Unix?
4. Я запускаю его в Linux, и чтение занимает около 2-3 минут. Я скоро опубликую код (возникли проблемы с моим Интернетом в системе Linux). Я публикую это с помощью Windows.
5. Можете ли вы на самом деле использовать Unix
grep
для переноса интересующих строк в код Perl?
Ответ №1:
Использование perl one liner и операторов range:
perl -ne 'print("$. $_") amp;amp; exit if (/abc/ .. 1) amp;amp; (/123/ .. 1) amp;amp; /opq/' file
Выводит:
11 opq //read this finally and print
Объяснение:
Переключатели:
-n
: Создаетwhile(<>){..}
цикл для каждой строки во входном файле.-e
: Указываетperl
выполнить код в командной строке.
Код:
print("$. $_")
: выводит номер строки$.
, за которым следует текущая строка$_
exit
: Завершите обработку после того, как будет найдена нужная строка.if (/abc/ .. 1) amp;amp; (/123/ .. 1) amp;amp; /opq/
: Найдите шаблоны по порядку.
Дополнение — для включения функциональности в скрипт
Я бы не советовал переходить к другому процессу perl для достижения этой функциональности. Вместо этого просто преобразуйте это в версию без командной строки:
use strict;
use warnings;
use autodie;
open my $fh, '<', 'file';
while (<$fh>) {
if ((/abc/ .. 1) amp;amp; (/123/ .. 1) amp;amp; /opq/) {
print "$. $_";
last;
}
}
Комментарии:
1. таким образом, я могу запустить это как system(«the_above_command») внутри моего perl-скрипта. Спасибо!
2. Я бы не советовал переходить к новому процессу perl, если вы можете этого избежать. Смотрите добавление.