【问题标题】:How to grep word from file如何从文件中grep单词
【发布时间】:2017-03-29 07:15:47
【问题描述】:

我想从另一个文件中 grep 文件中的一些单词。我的代码能够 grep 文件最后一行的单词,但不能grep 前面的单词。我不知道为什么,希望能在这里得到帮助。下面是我使用的 perl 脚本:

open(FILE1,"file1.txt") or die "Error, File1 could not open\n";           
open(FILE2,"file2.txt") or die "Error, File2 could not open\n";
open(FILE3, ">file3.txt") or die "Error, File3 could not open\n";

use strict; 
use warnings;
use List::MoreUtils qw(uniq);

my @file1=<FILE1>;
my @file2=<FILE2>;
my $j =0;
my $i =0;
my $zone =0;
for ($j=0; $j<=$#file2; $j++){
    $zone = $file2[$j];
    unless ( $zone =~ m/#(.*?)/ ) {
        print "$zone";
        my @fid = grep /$zone/ , @file1;
        @fid = uniq(@fid);
        s{^\s+|\s+$}{}g foreach @fid;                #cancel leading space
        for ($i=0; $i<=$#fid; $i++){
            print FILE3 "$fid[$i]\n";
        }
        #@fid=();

    }
}

close(FILE3);

我的 file1.txt 是这样的:

i am a dog
i am a cat
we are the fish
he is a boy
she is a girl

我的file2.txt是这样的:

is
am

但是我的file3只能显示那些包含am但不是is的句子,如果我把is放在第二行,am放在第一行,那么我的file3只包含is的句子。我不太确定为什么我的代码只能 grep 文件 2 中的最后一行。感谢您的帮助。

【问题讨论】:

    标签: regex perl grep


    【解决方案1】:

    从文件中读取时,最后的换行符是读取的每一行的一部分。您可以通过chomping 从模式数组中删除换行符:

    chomp( my @file2 = <FILE2> );
    

    【讨论】:

      【解决方案2】:

      你已经可以用 egrep 做到这一点了:

      egrep -f file2.txt file1.txt
      

      【讨论】:

        【解决方案3】:

        这个问题的根源是chomp - 你没有删除换行符,所以匹配不起作用。

        但除此之外,您的代码还有一些与寻址有关的问题:

        • 打开文件,你应该使用 3 arg open 和词法文件句柄,因为它的风格更好:open (my $file1, '&lt;', 'file1.txt' ) or die $!;
        • 而不是一个循环,您最好编译一个“匹配正则表达式”。
        • 您可以逐行迭代,而不是将所有文件读取到数组中,并且不需要使用内存。
        • 如果您正在迭代循环,并且 使用索引来访问当前元素,则最好使用foreach my $line ( @things ) { 类型语法。

        所以你的代码实际上可以简化为:

        #!/usr/bin/env perl
        use strict;
        use warnings;
        
        open(my $data, '<',"file1.txt") or die $!;
        open(my $search, '<', "file2.txt") or die $!;
        open(my $output, '>', "file3.txt" ) or die $!;
        
        chomp ( my @search_terms = <$search> );
        
        #quotemeta is needed to avoid 'special' regex characters doing things. 
        my $search_regex = join "|", map { quotemeta }, @search_terms;
        
        #note - '\b' denotes word boundary, which may not be what you want.  
        #means 'is' won't match 'fish'
        #so get rid of them if that's not what you want. 
        $search_regex = qr/\b($search_regex)\b/;
        
        print "Using: $search_regex\n";
        
        select $output; #default print destination
        while ( <$data> ) {
            print if m/$search_regex/;
        }
        

        输出(在'file3.txt'中):

        i am a dog
        i am a cat
        he is a boy
        she is a girl
        

        【讨论】:

          【解决方案4】:

          请试试这个。

          use strict; 
          use warnings;
          use List::MoreUtils qw(uniq);
          
          
          open(FILE1,"file1.txt") or die "Error, File1 could not open\n";           
          open(FILE2,"file2.txt") or die "Error, File2 could not open\n"; 
          open(FILE3, ">file3.txt") or die "Error, File3 could not open\n"; 
          
          my @file1=<FILE1>;
          my @file2=<FILE2>;
          my $j =0;
          my $i =0;
          
          foreach my $main_line(@file1){
              chomp($main_line);
              foreach my $line(@file2){
                  chomp($line);
                  if ($main_line =~ /$line/i) {
                      print FILE3 "$main_line\n";
                  }
              }
          }
          
          close(FILE3);
          

          谢谢, 呸呸呸~

          【讨论】:

          • 我认为对您“修复”的内容进行更多解释会有所帮助。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-11-12
          • 1970-01-01
          • 1970-01-01
          • 2011-05-06
          • 2012-03-02
          • 2011-02-22
          相关资源
          最近更新 更多