http://www.perlmonks.org?node_id=962571

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

Hi, I'm trying to search a number of large files containing a list of functions for commands that might be used multiple times. For example, If I want to find all the functions that issue the command 'ipconfig'. So I want to search the function file for 'ipconfig' and when I find it go BACK up through the file to find the function that issues this command. So search for string 'ipconfig' and when found find a previous line containing sub ...., then split this line to determine the function name. I've plenty of options to search for a specified string. I'm stuck when it comes to working back to the name of the function.
  • Comment on determine the name of a function that contains a specified string

Replies are listed 'Best First'.
Re: determine the name of a function that contains a specified string
by Ratazong (Monsignor) on Mar 30, 2012 at 11:23 UTC

    The easiest way would be not to go back: Just search for ipconfig and sub in parallel. If you find a sub, just store the related function-name (as this is the function you are currently in). And if you find an ipconfig, just take that name.

    update begin You could also do a two-pass-reading: in the first pass you would read all functions that are defined in your file, and store their name and the line where they start. In the second pass you would search for your keyword, check the line where it occurs and use this to determine the function name. update end

    You will of course still need to handle the case of your keywords occuring in strings, comments and so on...

    HTH, Rata
Re: determine the name of a function that contains a specified string
by moritz (Cardinal) on Mar 30, 2012 at 11:33 UTC

    One approach is to just read the whole file into a scalar, search for the desired command, then extract everything up to that command into a second string, and search for the last function definition inside that second string.

    Another approach is to read the file line by line, and when a match is found, open a second handle to that file, this time reading backwards (either File::ReadBackwards or PerlIO::reverse), seek to the position of the find, and then read (backwards) until the function definition is found.

    A third approach is to read the file in function chunks straight away, and then search each chunk for the commands.

Re: determine the name of a function that contains a specified string
by stevieb (Canon) on Mar 30, 2012 at 14:21 UTC
    #!/usr/bin/perl use warnings; use strict; use 5.10.0; my $search_term = 'ipconfig'; my %subs; my $name; while ( my $line = <DATA> ){ if ( $line =~ /^sub\s+/ ){ $name = (split /\s+/, $line)[1]; $subs{ $name } = 0; next; } $subs{ $name } = 1 if $line =~ /$search_term/; } while ( my ($k,$v) = each %subs ){ say "sub $k calls $search_term" if $v; } __DATA__ sub one { #one #two #three #ipconfig #four } sub two { #hello #there #wonderful #world } sub three { #ifconfig #ipconfig #nmap -sS -P0 localhost #tcpdump -n -i re0 -s 0 -w a.file

    EDIT: made it a bit more generic and descriptive

      Thanks for the perl module stevieb, unfortunately we are locked down as to what perl versions we can use. However you snipped of code above is exactly what I need :-D I just have to read up on hashes now to understand what you are doing :)
Re: determine the name of a function that contains a specified string
by stevieb (Canon) on Mar 31, 2012 at 03:52 UTC

    I was bored for a couple hours earlier today, so I wrote a module for this and upped it to the CPAN :)

    Devel::Examine::Subs

    Steve