2014-12-31 3 views
0

Я использую модуль File::Grep. Я следующий пример:Как использовать Perl-файл :: Grep module

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

use File::Grep qw(fgrep fmap fdo); 

my @matches = fgrep { 1.1.1 } glob "file.csv"; 

foreach my $str (@matches) { 
    print "$str\n"; 
} 

Но когда я пытаюсь напечатать $str значение, которое он дает мне HEX значение: GLOB(0xac2e78)

Что случилось с этим кодом?

+0

'использования Data :: Dumper; print Dumper \ @matches; 'скажет вам, как выглядят возвращаемые данные: – ysth

+0

' $ VAR1 = [ { 'filename' => 'file.csv', 'count' => 11, 'matches' => { '14' => '1.1.1, некоторые текстовые символы здесь' } } ]; ' – snoop

+0

что-то вроде этого. Я получаю совпадение после добавления использования' Data :: Dumper; '' print Dumper \ @matches; '. – snoop

ответ

2

документация не кажется, чтобы быть точными, но, судя по исходному коду — http://cpansearch.perl.org/src/MNEYLON/File-Grep-0.02/Grep.pm — перечня вы получите обратно из fgrep содержит один элемент на один файл. Каждый элемент представляет собой хэш-формы

{ 
    filename => $filename, 
    count => $num_matches_in_that_file, 
    matches => { 
     $line_number => $line, 
     ... 
    } 
} 

Я думаю, что было бы проще пропустить fgrep и его сложного возвратного значение, которое имеет намного больше информации, чем вы хотите, в пользу fdo, которая позволяет просто перебрать все строки файла и делать то, что вы хотите: (. Обратите внимание, что я удалил glob, кстати Там не много смысла писать glob "file.csv", так как только один файл может соответствовать этому globstring.)

fdo { my ($file, $pos, $line) = @_; 
     print $line if $line =~ m/1\.1\.1/; 
} 'file.csv'; 

или даже просто обойтись без этого модуля и написать:

{ 
    open my $fh, '<', 'file.csv'; 
    while (<$fh>) { 
     print if m/1\.1\.1/; 
    } 
} 
+0

Нет смысла удерживать блок фильтров OP '{1.1.1} ', поскольку он просто выберет все строки из каждого файла. – Borodin

+0

@Borodin: Да, ты прав. – ruakh

1

Я предполагаю, что вы хотите увидеть все строки, которые содержат file.csv1.1.1?

Документация для File::Grep не обновлена, но эта программа поместит в @lines все соответствующие строки из всех файлов (если их было несколько).

use strict; 
use warnings; 

use File::Grep qw/ fgrep /; 
$File::Grep::SILENT = 0; 

my @matches = fgrep { /1\.1\.1/ } 'file.csv'; 

my @lines = map { 
    my $matches = $_->{matches}; 
    @{$matches}{ sort { $a <=> $b } keys %$matches}; 
} @matches; 

print for @lines; 

Update

Самый Perlish способ сделать это как так

use strict; 
use warnings; 

open my $fh, '<', 'file.csv' or die $!; 

while (<$fh>) { 
    print if /1\.1\.1/; 
} 
+0

Наконец, я знаю, что в perl есть много способов добиться такого же ответа, путать, какой из них использовать. – snoop

+0

@snoop: Я добавил к своему ответу, чтобы объяснить, как использовать простой цикл чтения для достижения той же цели. – Borodin

+0

Но в вашем обновленном случае мы повторяем цикл while, его довольно много времени, вместо того, чтобы просто печатать текст из файла. Что будет лучше зацикливаться на данных или просто grep из файла? – snoop

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