2017-08-10 14 views
0

私のバックグラウンドを持つperlスクリプトの中でgrepを使用しています。perlでgrepを使って正規表現にマッチする

grep -r --include=*.txt -e '[a-zA-Z0-9]*\.[a-zA-Z]*$' $dir -n >> test.txt; 

ファイル名で終わる行をフィルタリングしようとしています。

例: FILE1.TXTが含まれています

This is a file about file.txt 
One of the files is sample.c 
Another example is test.doc 

しかし、私のgrepコマンドは何も返しません:

This is a file about file.txt 
This file is about algorithms. 
File.txtbis contains several functions. 
There are also several files. 
One of the files is sample.c 
Another example is test.doc 

が、私は私のgrepは、次の行を返すことを期待しています。

"$"記号を削除した場合、grepコマンドは正規表現と一致しないにもかかわらずファイルのすべての行を返します。

また、0以上ではなく1つ以上の文字を除外することをお勧めしますが、grepには*しかありません。 grepで "+"を1文字以上使用できますか?

backticksでgrepを使用する際に制限はありますか?

+0

'ファイル名で終わる行をフィルタリングする ' - どういう意味ですか?拡張?任意の拡張子? – fugu

+0

私は説明を更新しました。私は任意の拡張名を参照しています。 –

+0

'-e'を' -P'や '-E'に変更してください。 – CWLiu

答えて

0
#!/usr/bin/env perl 

use File::Find qw(find); 

# use File::Slurper qw(read_lines); 

sub read_lines { 
    my $file_name = shift; 
    open my $fh, "<", $file_name or die "Couldn't open $file_name: $!"; 
    my @buf = <$fh>; 
    close $fh; 
    chomp @buf; 
    return @buf; 
} 

find(
    { 
     no_chdir => 1, 
     wanted => sub { 
      my $file_path = $File::Find::name; 
      next unless -f $file_path; 
      my $file_name = $file_path; 
      $file_name =~ s/^.*\///; # drop everything until last '/' 

      for (read_lines($file_path)) { 
       print "$_\n" if m/\Q$file_name\E\s*$/; 
      } 
     }, 
    }, 
    '.' 
); 

あなたが他のファイルを参照する必要がある場合は、単にこのように、ルックアップの前にファイル名を蓄積する:。

#!/usr/bin/env perl 

use File::Find qw(find); 

# use File::Slurper qw(read_lines); 

sub read_lines { 
    my $file_name = shift; 
    open my $fh, "<", $file_name or die "Couldn't open $file_name: $!"; 
    my @buf = <$fh>; 
    close $fh; 
    chomp @buf; 
    return @buf; 
} 

my @file_paths =(); 

find(
    { 
     no_chdir => 1, 
     wanted => sub { 
      my $file_path = $File::Find::name; 
      next unless -f $file_path; 
      push @file_paths, $file_path; 
     }, 
    }, 
    '.' 
); 

my @file_names = map { 
    my $file_name = $_; 
    $file_name =~ s/^.*\///; # drop everything until last '/' 
    $file_name; 
} @file_paths; 

my $regexp = '(?:' . join('|', map { "\Q$_\E" } @file_names) . ')$'; 
$regexp = qr/$regexp/; 

for my $file_path (@file_paths) { 
    for (read_lines($file_path)) { 
     print "$_\n" if /$regexp/; 
    } 
} 
+0

@ chris-yo、これが役に立った場合は、回答の横にあるチェックマークを押して、それを承認済みとしてください。ありがとう! –

0

グレップ-Er --include = * TXT -e「[-はZa - Z0-9] +。[a-zA-Z] + $ '$ dir -n >> test.txt;