当前位置: 动力学知识库 > 问答 > 编程问答 >

How can I search multiple files for a string in Perl?

问题描述:

My question is probably simple but I'm a complete newbie. I want to search the contents of multiple text files for a particular phrase and then display the lines of the finds on screen. I've already learnt how to deal with a single file. For example, if I want to search for a word, say "Okay" in a text file named "wyvern.txt" in the root directory of F. The following code works:

#!/usr/bin/perl

$file = 'F:\wyvern.txt';

open(txt, $file);

while($line = <txt>) {

print "$line" if $line =~ /Okay/;

}

close(txt);

But what should I do if I want to search for the same phrase in two text files, say "wyvern' and "casanova" respectively? or how about all the files in the directory "novels" in the root directory of F.

Any help would be greatly appreciated.

Thanks in advance

Mike

Edit:

Haha, I finally figured out how to search all the files in a directory for a pattern match:)

The following code works great:

#!/usr/bin/perl

@files = <F:/novels/*>;

foreach $file (@files) {

open (FILE, "$file");

while($line= <FILE> ){

print "$line" if $line =~ /Okay/;

}

close FILE;

}

网友答案:

Extending the good answer provided by Jonathan Leffler:

The filename where the match was found is in $ARGV, and with a small change, the line number can be found in $.. Example:

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

Furthermore, if you have a list of filenames and they're not on the commandline, you can still get the magic ARGV behavior. Watch:

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

Which is a generally useful pattern for doing line-by-line processing on a series of files, whatever it is -- even if I might recommend File::Grep or App::Ack for this specific problem :)

网友答案:

The easiest way is to list the files on the command line, and then simply use:

while (<>)
{
    print if m/Okay/;
}
网友答案:

On a system where command line arguments are properly expanded, you can use:

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

The problem with Windows is:

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

On Windows, you could do:

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

But, you might just want to use cmd.exe builtin findstr or the grep command line tool.

网友答案:

File::Grep is what you need here

网友答案:

put the files in a for loop, or something along those lines:

i.e.

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

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

Just a tweak on your line: <F:/novels/*>, I prefer to use the glob keyword - it works the same in this context and avoids the chances of confusing the many different uses of angle brackets in perl. Ie:

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

See perldoc glob for more.

网友答案:

Okay, I'm a complete dummie. But to sum up, I now can search one single text file or multiple text files for a specified string. I'm still trying to figuring out how to deal with all the files in one folder. the following codes work.

Code 1:

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

Code 2:

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

Thanks again for your help. I really appreciate it.

分享给朋友:
您可能感兴趣的文章:
随机阅读: