How to search in windows all the files in a directory?

Hi ,

I have about 100 files saved in my windows directory. I  have to search and create report in all the files stored in the directory where select, insert and update and some other words are being used.

I want to write a program where i can specify all the words and it should give me the list of all the files where the word is being used.

file a:  ssjj jjk  bbnn  select
file b:  jjjk  uuu bbdfm iuirui
          hhhf kkkll  llll   update

The report should be like

filea    select
fileb    update

Thanks,
FUFA
prasadp2009Asked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

wilcoxonCommented:
This should do what you want.  If you don't want the : after the filename, feel free to change it to tab, more spaces, or whatever.
use strict;
use warnings;
use Tie::File;

my $dir = '/Windows';
my @words = qw(update select insert delete);
# alternately to read them from the command line, uncomment below
# my $dir = shift;
# my @words = @ARGV;

chdir $dir or die "could not cd to $dir: $!";
opendir DIR, '.' or die "could not open dir: $!";
# get the files (skip dirs)
my @files = grep { -f $_ } readdir DIR;
closedir DIR;

# process files
foreach my $fil (@files) {
    my @lines;
    tie @lines, 'Tie::File', $fil or die "could not tie file $fil: $!";
    # check each word
    my @found;
    foreach my $word (@words) {
        # if the first \b doesn't work, try (?:^|\s) - I've had trouble on occasion
        my @tmp = grep m{\b$word\b}, @lines;
        push @found, $word if @tmp;
    }
    untie @lines;
    print $fil, ': ', join(' ', @found), "\n" if @found;
}

Open in new window

0
prasadp2009Author Commented:
Does the grep works in windows too?

And  i havenot yet tried the solution...

-FUFA
0
wilcoxonCommented:
grep is a standard perl function so it will work in any perl program.
0
Introduction to Web Design

Develop a strong foundation and understanding of web design by learning HTML, CSS, and additional tools to help you develop your own website.

prasadp2009Author Commented:
Nice , I will try and send  you the solution.
-Fufa
0
wilcoxonCommented:
There's a chance Tie::File might give errors when doing binary files.  If the files you want to search are named in a predictable manner, you could change this line:

my @files = grep { -f $_ } readdir DIR;

to something like this:

my @files = grep { -f $_ and /\.txt$/ } readdir DIR;

with the regex matching the pattern of the files you want to search (the above being *.txt).
0
prasadp2009Author Commented:
Can't load 'C:\oracle\product\10.2.0\db_1\perl\5.8.3\lib/MSWin32-x86-multi-threa
d/auto/POSIX/POSIX.dll' for module POSIX: load_file:The specified module could n
ot be found at C:\oracle\product\10.2.0\db_1\perl\5.8.3\lib/MSWin32-x86-multi-th
read/XSLoader.pm line 68.
 at C:\oracle\product\10.2.0\db_1\perl\5.8.3\lib/MSWin32-x86-multi-thread/POSIX.
pm line 26
Compilation failed in require at C:\oracle\product\10.2.0\db_1\perl\5.8.3\lib/Ti
e/File.pm line 5.
BEGIN failed--compilation aborted at C:\oracle\product\10.2.0\db_1\perl\5.8.3\li
b/Tie/File.pm line 5.
Compilation failed in require at c:\perl\get_p.pl line 3.
BEGIN failed--compilation aborted at c:\perl\get_p.pl line 3.

These error messages i am getting bez of use Tie::File. Can we use something else?
0
wilcoxonCommented:
Very strange.  It looks like you have Tie::File installed in your perl install but not POSIX even though I'm pretty sure POSIX is part of core perl.

The below should work but will be less efficient and use more memory.
use strict;
use warnings;

my $dir = '/Windows';
my @words = qw(update select insert delete);
# alternately to read them from the command line, uncomment below
# my $dir = shift;
# my @words = @ARGV;

chdir $dir or die "could not cd to $dir: $!";
opendir DIR, '.' or die "could not open dir: $!";
# get the files (skip dirs)
my @files = grep { -f $_ } readdir DIR;
closedir DIR;

# process files
foreach my $fil (@files) {
    my @lines;
    # read the file into memory
    open IN, $fil or die "could not open $fil: $!";
    my $data = join '', <IN>;
    close IN;
    # check each word
    my @found;
    foreach my $word (@words) {
        # if the first \b doesn't work, try (?:^|\s) - I've had trouble on occasion
        if ($data =~ m{\b$word\b}ms) {
            push @found, $word;
        }
    }
    print $fil, ': ', join(' ', @found), "\n" if @found;
}

Open in new window

0
prasadp2009Author Commented:
Hi  ,

Thanks this solution works. Can you pls write this program to recursively look into the sub dirrectories
inside the root directory.


Thanks,
Pooja
0
prasadp2009Author Commented:
And it could do the search like the following eg.

insert into contact values (   );;
insert  into xyz values (   );
update tab2 set x=y;
select * from tab1;
I want the result like
operation  table
insert       contact
insert       xyz
update     tab2
select      tab1



Thanks,
Fufa
0
wilcoxonCommented:
Here is code that will recursively search sub-dirs.

The changes needed to parse the sql to extract table info are much more complex (and are not what you originally asked for).  Are all sql statements always on only one line?  Are all sql statements valid?  Do they all use the same syntax (eg insert vs insert into, delete vs delete from, etc)?

Do you still want the file name in the report or just the sql op and the table name?

I would suggest opening a second question referencing this one asking about outputting the new report format you want with the above questions answered.
use strict;
use warnings;

my $base = '/Windows';
my @words = qw(update select insert delete);
# alternately to read them from the command line, uncomment below
# my $dir = shift;
# my @words = @ARGV;

chdir $base or die "could not cd to $base: $!";
process_dir('.');

sub process_dir {
my ($dir) = @_;
opendir DIR, $dir or die "could not open dir $dir: $!";
# get the files (skip dirs)
my @entries = readdir DIR;
closedir DIR;
my @files = grep { -f $_ } @entries;
my @dirs = grep { -d $_ } @entries;

# process files
foreach my $fil (@files) {
    my @lines;
    # read the file into memory
    open IN, "$dir/$fil" or die "could not open $dir/$fil: $!";
    my $data = join '', <IN>;
    close IN;
    # check each word
    my @found;
    foreach my $word (@words) {
        # if the first \b doesn't work, try (?:^|\s) - I've had trouble on occasion
        if ($data =~ m{\b$word\b}ms) {
            push @found, $word;
        }
    }
    print "$dir/$fil: ", join(' ', @found), "\n" if @found;
}

# process dirs
foreach my $sdir (@dirs) {
    process_dir("$dir/$sdir");
}
} # end sub

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
prasadp2009Author Commented:
Hi ,

I will try the solution and let u know.

Thnaks & Regds,
Fufa
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Perl

From novice to tech pro — start learning today.