2010-09-24 1 views
4

У меня есть простой файл журнала, который очень грязный, и мне нужно, чтобы он был аккуратным. Файл содержит заголовки журналов, но все они смешаны вместе. Поэтому мне нужно отсортировать файлы журнала в соответствии с заголовками журналов. Нет статического числа строк - это означает, что нет фиксированного количества строк для каждого заголовка текстового файла. И я использую perl grep для сортировки заголовков.Как я могу grep и сортировать текстовые файлы с помощью Perl?

Файлы журнала выходит что-то вроде этого:

Car LogFile Header 
<text> 
<text> 
<text> 
Car LogFile Header 
<text> 
Car LogFile Header 
<and so forth> 

Я застегнуты/искал простой алгоритм, но не кажется, что это будет работать. Может ли кто-нибудь направить меня? Благодаря!

#!/usr/bin/perl 

#use 5.010; # must be present to import the new 5.10 functions, notice 
#that it is 5.010 not 5.10 


my $srce = "./root/Desktop/logs/Default.log"; 
my $string1 = "Car LogFile Header"; 
open(FH, $srce); 
my @buf = <FH>; 
close(FH); 
my @lines = grep (/$string1/, @buffer); 

После выполнения кода на терминале нет результата. Есть идеи?

+0

Ну, если вы хотите показать результаты, вы должны что-то выводить. –

+0

Сначала вы используете '@ buf', но затем называете его' @ buffer'. – Frank

ответ

10

Я думаю, что вы хотите что-то вроде:

my $srce = "./root/Desktop/logs/Default.log"; 
my $string1 = "Car LogFile Header"; 

open my $fh, '<', $srce or die "Could not open $srce: $!"; 

my @lines = sort grep /\Q$string1/, <$fh>; 
print @lines; 

Убедитесь, что у вас есть правильный путь к файлу, и файл имеет линии, соответствующие вашей тестовой схеме.

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

+0

Я не понимаю, почему «my» в $ fh заставляет систему давать эту ошибку сейчас. «Глобальный символ» $ scre «требует явного имени пакета», так как $ srce не должен иметь никаких проблем. – JavaNoob

+1

@JavaNoob: потому что «$ scre» не пишется так же, как «$ srce». –

+0

Упс ..... Не замечал, что спасибо .. Но кажется, что коды печатают только заголовок, а не абзац. Наверное, вопрос должен быть задан неправильно. Во всяком случае, это правильный ответ. – JavaNoob

0

Perl grep не такой же, как Unix grep, поскольку он ничего не печатает на экране.

Общий синтаксис: grep Expr, LIST

Оценивает Expr для каждого элемента LIST и возвращает список, состоящий из тех элементов, для которых выражение оценивали с true.

В вашем случае будут возвращены все элементы @buffer, у которых есть долина $string1.

Затем вы можете распечатать массив @buffer, чтобы увидеть их на самом деле.

+0

Я не понимаю ваш смысл .... – JavaNoob

+0

Он означает, что вы не можете просто определить массив и ожидать от него выход на экран. Чтобы получить выход на экран, вам нужно «распечатать» массив. – Frank

0

Вы только что сохранили все в массиве, а не распечатываете его. Также не обязательно хранить весь файл в памяти. Вы можете прочитать и распечатать строку результатов матчей по линии, как это:

my $srce = "./root/Desktop/logs/Default.log"; 
my $string1 = "Car LogFile Header"; 
open(FH, $srce); 
while(my $line = <FH>) { 
    if($line =~ m/$string1/) { 
    print $line; 
    } 
} 
close FH; 
+0

Пока ничего не отображается. Он просто пропускает пустую строку в терминале. – JavaNoob

+0

Нет, попробуйте с текстом журнала, который вы указали выше. Он выведет все строки заголовка «Автомобильный журнал», которые он может найти. – Frank

2

Всегда используйте:

use strict; 
use warnings; 

Это сказал бы вам, что @buffer не определен.

#!/usr/bin/perl 

use strict; 
use warnings; 

my $srce = "./root/Desktop/logs/Default.log"; 
my $string1 = "Car LogFile Header"; 
open(my $FH, $srce) or die "Failed to open file $srce ($!)"; 
my @buf = <$FH>; 
close($FH); 
my @lines = grep (/$string1/, @buf); 
print @lines; 

Perl является сложным для специалистов, поэтому специалисты используют предупреждения он обеспечивает, чтобы защитить их от ошибок. Начинающие должны использовать предупреждения, чтобы они не совершали ошибок, которые они даже не знают, что они могут сделать.

(Потому что вы не получили шанс chomp входные линии, у вас еще есть новые строки в конце так в print гравюр заголовки одному в каждой строке.)

+0

появляется ошибка «readline() на закрытом дескрипторе файла $ FH на ./rgex.pl строке 9.». Любые мысли по этому поводу? – JavaNoob

+1

Если вы проверили возвращаемое значение open(), вы поймали бы это. –

+0

Какую версию Perl вы используете? Это работало нормально для меня, вырезано из ответа, с 5.13.4, 5.10.1, 5.8.8. Он потерпел неудачу с 5.6.2 - не смог найти строгую, что немного озадачило ... OTOH, это была сборка PowerPC Perl, работающая на моем (Intel) Mac с помощью Snow Leopard (10.6.4), и я не использовал это в течение длительного времени. –

1

Я не думаю, что grep - это то, что вы действительно хотите. Как вы указали в ответе Брайана, grep даст вам только заголовки, а не последующие строки.

Мне кажется, вам нужен массив, где каждый элемент является заголовком и последующими строками до следующего заголовка.

Что-то вроде: -

#!/usr/bin/perl 

use strict; 
use warnings; 

my $srce = "./default.log"; 
my $string1 = "Car LogFile Header"; 
my @logs; 
my $log_entry; 
open(my $FH, $srce) or die "Failed to open file $srce ($!)"; 

my $found = 0; 
while(my $buf = <$FH>) 
{ 
    if($buf =~ /$string1/) 
    { 
     if($found) 
     { 
      push @logs, $log_entry; 
     } 

     $found = 1; 
     $log_entry = $buf; 
    } 
    else 
    { 
     $log_entry = $log_entry . $buf; 
    } 
} 

if($found) 
{ 
    push @logs, $log_entry; 
} 

close($FH); 

print sort @logs; 

я думаю, что это то, что в настоящее время просят.

-1

Здравствуйте, я нашел способ извлечь ссылки из HTML-файла

!/USR/бен/Perl -w

2 
    3 # Links graber 1.0 
    2 
    3 # Links graber 1.0 
    4 #Author : peacengell 
    5 #28.02.13 
    6 
    7 #### 
    8 
    9 my $file_links = "links.txt"; 
10 my @line; 
11 my $line; 
12 
13 
14 open(FILE, $file_links) or die "Can't find File"; 
15 
16 while (<FILE>) { 
17 chomp; 
18 $line = $_ ; 
19 
20 @word = split (/\s+/, $line); 
21 @word = grep(/href/, @word); 
22 foreach $x (@word) { 
23 
24 if ($x =~ m /ul.to/){ 
25 $x=~ s/href="//g; 
26 $x=~s/"//g; 
27 print "$x \n"; 
28 
29       
30       } 
31     
32     } 
33   
34   } 

вы можете использовать его и изменить его, пожалуйста, дайте мне знать, если вы измените его ,

Смежные вопросы