I want to look for a string in all the files in a directory in perl. But the following code is not working
if ($^O eq "MSWin32") {
my @results = `findstr /s "Hello" /d:\\Testing`;
print "my results \n @results\n";
#or
system('findstr /s "Hello" /d:\\Testing');
}
I am running the script from "C:" and it contains "Testing" directory. For the non windows system it works perfectly fine using grep system command. Please help. Thanks
You're not using findstr correctly.
findstr /?
)With all those in mind, a working findstr command would be
findstr /s /d:"Testing" *
If you just need the filenames containing matches (not the content of line in the file with the match), use the /m
switch
findstr /s /m /d:"Testing" *
Also the /s
switch is not needed if you don't need recursive searching (e.g. search the subdirectory of C:\Testing)
Another thing to note is that if you use /d:"Testing"
, the first line of the output would be
Testing:
which would end up as the first element in your array. To counter this, you can shift
your array, or better still, change the working directory to Testing in Perl.
The code snippet below shows how I would rewrite this
#!/usr/bin/env perl
use strict;
use warnings;
if ($^O eq "MSWin32") {
chdir("Testing");
my @results = qx'findstr /s /m "Hello" *';
local $" = ", ";
@results = map { s/^/Testing\\/; chomp; $_ } @results;
chdir("..");
print "my results \n@results\n";
}
Other notes (god, this post is too long already!):
qx'...'
is somewhat equivalent to `...`
except that whatever is in between is not interpolated.$"
is the separator used for array elements when the array is interpolated within double quotes in a print
or say
(once you get the code working, change its value to see what it does)map
does some processing on each element of the array
s/^/Testing\\/
prefixes each filename with "Testing**" (so that your results will be **relative to C: instead of relative to Testing)chomp
removes trailing whitespace character (e.g. newline) from the result$_
makes sure that it returns the modified filename (instead of the return value of s///
which is # substitution)You can go one step further and parameterize the folder name ("Testing") and string-to-search in the code, and even get user input for those parameters. But that is left as an exercise to the reader (because I'm le tired and the post is already too long)