String 读取搜索字符串的文件并打印其路径

String 读取搜索字符串的文件并打印其路径,string,perl,file,search,String,Perl,File,Search,我试图用Perl编写一个脚本,搜索特定目录和所有子目录。这样做的目的是脚本必须读取目录和所有子目录中的所有文件,以查找特定的文本字符串(我定义的任何字符串)。如果在文件中找到字符串,则脚本将在新文本文件中打印文件的路径和名称,并继续处理目录树中的所有文件 我有这样的事情,但我不知道如何继续下去。我是Perl的初学者,对所有的选项都一无所知 #!/usr/bin/perl use strict; use File::Find; my $dir = 'C:\PATH\TO\DIR'; my $st

我试图用Perl编写一个脚本,搜索特定目录和所有子目录。这样做的目的是脚本必须读取目录和所有子目录中的所有文件,以查找特定的文本字符串(我定义的任何字符串)。如果在文件中找到字符串,则脚本将在新文本文件中打印文件的路径和名称,并继续处理目录树中的所有文件

我有这样的事情,但我不知道如何继续下去。我是Perl的初学者,对所有的选项都一无所知

#!/usr/bin/perl
use strict;
use File::Find;

my $dir = 'C:\PATH\TO\DIR';
my $string = "defined";

find(\&printFile, $dir);
sub printFile {
   my $element = $_;
   open FILE, "+>>Results.txt";
   if(-f $elemento && $elemento =~ /\.txt$/) {
       my $boolean = 0;
       open CFILE, $elemento;
       while(<CFILE>) {  
           if ($string) {
               print FILE "$File::Find::name\n"; 
           }
           close CFILE;
      }
   }
   close FILE;
}

sleep(5);
#/usr/bin/perl
严格使用;
使用File::Find;
my$dir='C:\PATH\TO\dir';
my$string=“defined”;
查找(\&printFile,$dir);
子打印文件{
我的$element=$\ux;
打开文件“+>>Results.txt”;
如果(-f$elemento&&$elemento=~/\.txt$/){
我的$boolean=0;
打开CFILE,$elemento;
while(){
如果($string){
打印文件“$FILE::Find::name\n”;
}
关闭文件;
}
}
关闭文件;
}
睡眠(5);

虽然离你不远,但有些事情你需要改变

#!/usr/bin/perl
use strict;
use warnings;  # never go without warnings
use File::Find;

my $dir = 'C:\PATH\TO\DIR';
my $string = "defined";
open my $out, ">>", "Results.txt" or die $!;  # move outside, change mode, 
                                              # 3-arg open, check return value
find(\&printFile, $dir);

sub printFile {
   my $element = $_;
   if(-f $element && $element =~ /\.txt$/) { # $elemento doesn't exist
       open my $in, "<", $element or die $!;
       while(<$in>) {
           if (/\Q$string\E/) {  # make a regex and quote metachars 
               print $out "$File::Find::name\n"; 
               last;             # stop searching once found
           }
      }
   }  # lexical file handles auto close when they go out of scope
}
然后将输出打印到标准输出

print "$File::Find::name\n"; 
用法:

perl script.pl c:/path/to/dir > output.txt
正如其他人在评论中指出的那样,这很容易用递归方法解决。但不幸的是,您似乎正在使用Windows,在这种情况下,它不是一个选项(据我所知)。

#行在Windows平台上是不相关的,在Unix上只是一种方便。你最好把它省略掉

您的程序基本上是正确的,但避免了Perl为使代码更加简洁和易于理解而提供的许多便利

您应该始终将
use warnings
添加到
use strict
中,因为它会拾取您可能忽略的简单错误

打开文件时应使用词法文件句柄和三参数形式的
open
,并且应检查它们是否成功,因为打开文件失败会使大多数后续代码无效。惯用的open如下所示

open my $fh, '<', 'myfile' or die $!;

如果这是你真正需要做的,你可以看看。默认情况下,它将搜索子目录,以及grep上的其他增强功能。当然,如果这是一个更大的Perl脚本,那么您可以使用它,或者使用其他发布的答案之一

$ ack include
将返回类似于

src/draw.c
27:#include <stdio.h>
28:#include <stdlib.h>
29:#include "parsedef.h"
31:#include "utils.h"
32:#include "frac.h"
33:#include "sscript.h"

src/utils.c
27:#include <stdio.h>
28:#include <stdlib.h>
29:#include <string.h>

也许您更愿意使用多种实现中的一种,而不是使用自己的实现。如上所述,您可以使用Perl的
grep()
函数。根据经验,我建议您将输出到STDIN而不是文件(只需
print()
it)。您可以使用重定向将输出重定向到文件。这使得脚本更加灵活(例如,将输出管道化到另一个进程,等等)。我曾尝试使用grep,但它没有给我想要的结果,因为它没有显示包含的所有子目录。这就是我试图寻找另一种解决方案的原因。@m0skit0:Perl的
grep
不能做到这一点:它过滤Perl列表而不是文件。你不能输出到STDIN,好的,我理解错了。我认为字符串在文件名中:PThank you TLP它的工作非常完美。然后您可以解释
如果(-f$element&&$element=~/\.txt$/)
那么
-f
的含义是什么?在中进行了描述
$ ack include
src/draw.c
27:#include <stdio.h>
28:#include <stdlib.h>
29:#include "parsedef.h"
31:#include "utils.h"
32:#include "frac.h"
33:#include "sscript.h"

src/utils.c
27:#include <stdio.h>
28:#include <stdlib.h>
29:#include <string.h>
$ ack -l include

lib/Text/AsciiTeX.xs
src/limit.c
src/sscript.c
src/dim.c
src/frac.c
src/brace.c
src/symbols.c
src/sqrt.c
src/array.c
src/ouline.c
src/draw.c
src/utils.c
src/asciiTeX.c