如何在Perl中搜索多个文件中的字符串?

时间:2009-10-03 03:44:24

标签: perl

我的问题可能很简单,但我是一个完整的新手。我想搜索特定短语的多个文本文件的内容,然后在屏幕上显示查找的行。我已经学会了如何处理单个文件。例如,如果我想搜索一个单词,请在F的根目录中名为“wyvern.txt”的文本文件中说“Okay”。以下代码有效:

#!/usr/bin/perl

$file = 'F:\wyvern.txt';
open(txt, $file);
while($line = <txt>) {
  print "$line" if $line =~ /Okay/;
}
close(txt);

但是,如果我想在两个文本文件中搜索相同的短语,分别说“wyvern”和“casanova”,或者如何在F的根目录中的“novels”目录中的所有文件怎么办?

非常感谢任何帮助。 提前致谢

麦克

修改

哈哈,我终于想出了如何搜索目录中的所有文件以进行模式匹配:) 以下代码非常有用:

#!/usr/bin/perl  
@files = <F:/novels/*>;
foreach $file (@files) {
open   (FILE, "$file");
while($line= <FILE> ){
print "$line" if $line =~ /Okay/;
}
close FILE; 
} 

7 个答案:

答案 0 :(得分:8)

扩展Jonathan Leffler提供的好答案:

找到匹配项的文件名位于$ARGV,只需稍加更改即可在$.中找到该行号。例如:

while (<>) {
  print "$ARGV:$.:$_" if /pattern/;
} continue {
  close ARGV if eof; # Reset $. at the end of each file.
}

此外,如果您有一个文件名列表但它们不在命令行上,您仍然可以获得神奇的ARGV行为。观看:

{
  local @ARGV = ('one.txt', 'two.txt');
  while (<>) {
    print "$ARGV:$.:$_" if /Okay/;
  } continue {
    close ARGV if eof;
  }
}

对于对一系列文件进行逐行处理,这是一种非常有用的模式,无论它是什么 - 即使我可能会为此推荐File::GrepApp::Ack 问题:)

答案 1 :(得分:4)

在正确扩展命令行参数的系统上,您可以使用:

[sinan@host:~/test]$ perl -ne 'print "$.:$_" if /config/' *
1:$(srcdir)/config/override.m4

Windows的问题是:

C:\Temp> perl -ne "print if /perl/" *.txt
Can't open *.txt: Invalid argument.

在Windows上,你可以这样做:

C:\Temp> for %f in (*.txt) do perl -ne "print if /perl/" %f

但是,您可能只想使用cmd.exe内置findstrgrep命令行工具。

答案 2 :(得分:3)

最简单的方法是在命令行列出文件,然后只使用:

while (<>)
{
    print if m/Okay/;
}

答案 3 :(得分:2)

你需要

File::Grep

答案 4 :(得分:2)

只需对您的行进行调整:<F:/novels/*>,我更喜欢使用glob关键字 - 它在此上下文中的工作方式相同,并避免在perl中混淆尖括号的多种不同用法的可能性。即:

@files = glob "F:/novels/*";

有关详情,请参阅perldoc glob

答案 5 :(得分:1)

将文件放在for循环中,或者沿着这些行放置:

for $file ('F:\wyvern.txt','F:\casanova.txt') {

open(TXT, $file);
while($line = <txt>) {
     print "$line" if $line =~ /Okay/;
    }
close TXT;
}

答案 6 :(得分:0)

好的,我是一个完全的dummie。但总而言之,我现在可以搜索一个文本文件或多个文本文件来查找指定的字符串。我还在试图弄清楚如何处理一个文件夹中的所有文件。 以下代码有效。

代码1:

#!/usr/bin/perl
$file = 'F:\one.txt';
open(txt, $file);
while($line = <txt>) {
  print "$line" if $line =~ /Okay/;
}
close(txt);

代码2:

#!/usr/bin/perl
{
  local @ARGV = ('F:\wyvern.txt', 'F:\casanova.txt');
  while (<>) {
    print "$ARGV:$.:$_" if /Okay/;
  } continue {
    close ARGV if eof;
  }
}

再次感谢您的帮助。我真的很感激。