Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Parse for a name after a keyword search in all the files, given directory as input

by prash_sri (Initiate)
on Feb 17, 2017 at 07:19 UTC ( [id://1182188]=perlquestion: print w/replies, xml ) Need Help??

prash_sri has asked for the wisdom of the Perl Monks concerning the following question:

#!/usr/local/bin/perl $dir = $ARGV[0]; open(HANDLE,$dir) || die "ERROR in opening file"; @allfiles = readdir HANDLE; close(HANDLE); foreach $files (@allfiles) { open(FH,"<",$files)|| die "ERROR in opening file"; foreach $line (<FH>) { $line =~ m/ \^module\ /g ; @next = split(/\s+/,$line); } close(FH); } print "$next[0]\n"

Trying to write a perl code which browses all the files recursively under a given input directory and do the following: - Parse all the list of module names. - Parse all the instance names inside each of the modules. Kindly let me know where am I going wrong!! And guide me for obtaining the correct output. Thanks

  • Comment on Parse for a name after a keyword search in all the files, given directory as input
  • Download Code

Replies are listed 'Best First'.
Re: Parse for a name after a keyword search in all the files, given directory as input
by haukex (Archbishop) on Feb 17, 2017 at 08:29 UTC

    Hi prash_sri,

    In your code, you are using open instead of opendir, this won't work. If you had warnings turned on, you would have been warned about this, see Use strict and warnings. Also, as documented in readdir, you should prepend the name of the directory to the filename, and note that it will return every entry in the directory, including subdirectories, which you can filter with perl's -f filetest operator, and including the special directories . and .., which you can filter with File::Spec's no_upwards (although the aforementioned -f test would filter them too). See the examples under readdir.

    Trying to write a perl code which browses all the files recursively under a given input directory

    If by recursively you mean that you want to look into subdirectories too, then I would recommend File::Find over readdir/opendir, or perhaps one of the easier-to-use modules File::Find::Rule, Path::Class's recurse function, or Path::Tiny's visit function. Personally I like Path::Class, but I can recommend any of the modules I mentioned here.

    Regards,
    -- Hauke D

    Update: s/including \Kdir/subdir/

Re: Parse for a name after a keyword search in all the files, given directory as input
by choroba (Cardinal) on Feb 17, 2017 at 08:36 UTC
    > all the files recursively

    There's no recursion happening in the code. To use recursion, you have to move the code to a subroutine, and call that subroutine from itself (when entering a subdirecory). Another approach would be to shift from @allfiles in a while-loop instead of foreach , and pushing the new directories back to @allfiles for further processing.

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
Re: Parse for a name after a keyword search in all the files, given directory as input
by hippo (Bishop) on Feb 17, 2017 at 08:08 UTC
    Kindly let me know where am I going wrong!!

    Unfortunately you have not said how it is going wrong and since we don't have your tree of files to run it on it's all down to guesswork. See SSCCE. "It doesn't work" is as useful to a developer as "I'm ill" is to a medic. Be specific.

    Also, the lack of strict and warnings is a bad sign. See the Basic Debugging Checklist.

    Best guess is that your regex is wrong. Is the exact string you wish to find " ^module " with all that whitespace and the caret?

      What I intend to do is, There is a directory, consisting of 10 files in .v format; I feed in the path for directory in command line and my code has to open all the files in the directory, and look for the word modulekeyword present at the starting of any line in the entire file for all the 10 files, and it should print the word next to moduleconsidered as keyword one in each line. As my .v file has multiple 'module' keywords.

      Ex : file.v
      Line No.2> module GATES(clock,variable); .... .... Line No.100> module FF(op, ip,);

      Output expected- GATES in 1st line FF in 2nd line

        So now we know in a little more detail what you want your script to do. Unfortunately you still have not said in what way it is going wrong.

        Here then are a few suggestions.

        1. Read, understand and implement at least the first 2 steps of the Basic Debugging Checklist. Do this now, before anything else.
        2. Test to see if you are actually looping over all files in the directory. At the very least print a count of all the files you have tested by the end of the script.
        3. Test your regex (which we now know is wrong). A simple perlish grep will do: perl -ne '/^module / and print' somedir/filename.v and then modify the regex until it extracts what you want.
        4. If you still can't get the required output then post back here stating precisely in what way your code fails and providing an SSCCE

        Happy debugging!

Re: Parse for a name after a keyword search in all the files, given directory as input
by Discipulus (Canon) on Feb 17, 2017 at 09:01 UTC
    Hello prash_sri and welcome to the monastery and to the wonderful world of Perl!

    This of traversing directory structure is one of the first question asked here in the monastery: node id 847

    Please read elder's wisdom: see Recursive Directory print where I point to the tachyon's solution.

    Note that since that time you can now use local variable to open dirs like open my $dir instead of bareword DIRHANDLE syntax

    opendir my $path or die "unable to open '$path' dir for read!"

    See opendir readdir telldir seekdir rewinddir and closedir pages.

    L*

    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
Re: Parse for a name after a keyword search in all the files, given directory as input
by LanX (Saint) on Feb 17, 2017 at 13:28 UTC
Re: Parse for a name after a keyword search in all the files, given directory as input (Verilog)
by toolic (Bishop) on Feb 17, 2017 at 14:50 UTC
    If your Verilog files are very simple, you don't even need Perl. You can just use grep:
    grep -w module *.v

    If your files are not so simple, then you should use a Verilog parser: Verilog-Perl. For example, if some of your modules are commented out, or if the module keyword is not on the same line as the module name, etc.

Re: Parse for a name after a keyword search in all the files, given directory as input
by kcott (Archbishop) on Feb 18, 2017 at 00:11 UTC

    G'day prash_sri,

    Welcome to the Monastery.

    I see you've received copious, excellent advice on things to fix.

    When you've fixed all those issues, and finally want to open a specific file, remember that the file is in $dir, which is not necessarily the current directory: open "$dir/$file", not $file.

    When dealing with a single item, use the singular form, as I did in the previous paragraph: use $file not $files (which looks like an arrayref to me, e.g. my $files = \@files;).

    Also, you might find the autodie pragma useful.

    — Ken

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1182188]
Approved by marto
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (8)
As of 2024-04-19 15:34 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found