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

hi guys, i'd like to know how i can actually get the name of the file that is currently being used. apparently printing $0 will print the full path..while $ARGV is printing nothing! i'd like to print only the name of the file

Replies are listed 'Best First'.
Re: get file name?
by Corion (Patriarch) on Feb 25, 2008 at 07:57 UTC

    $0 and $ARGV are two different things that could fall under "currently being used".

    $0 is the (file name of the) program currently being executed.

    $ARGV is the (file name of the) file currently being processed in a <> loop.

    File::Basename has the routines to extract parts of the names from either.

      Hi,
      You can use a simple RegEx to extract the file name from $0
      For example:
      $0 =~ /(.*\/)*(.+)/; print $2;
      UPDATE: The above RegEx has been written for Linux

        Or of course there is split

        my $file_name = ( split m{/}, $0 )[-1];
        not to mention substr and rindex
        my $file_name = substr $0, 1 + rindex $file, '/';
        if you insist on regular expressions then this is simpler
        my ( $file_name ) = $0 =~ m{([^/]+)$};

        If you care about portability, and one day you will, even if its just to port your code back into your brain in six months time, you will stick to Corion's suggested

        use File::Basename qw(basename); my $file_name = basename $0;

        I think nikil.patil's regex has some shortcomings:
        For example, if executed from a directory OTHER than the one containing the script, the path is NOT stripped. On windows (which is all I have readily available today) execution looks like this:

        C:\>perl f:\_wo\pl_test\669947.pl $0 is: f:\_wo\pl_test\669947.pl nikhil.patil's $2 is: f:\_wo\pl_test\669947.pl
        (The code for the above is part of the code block which follows this paragraph.)

        So, in the interest of posting a reply with more than mere criticism, I tried several approaches, including several variations on lookarounds, of which this is one that failed less spectacularly than others:

        #!C:/Perl/bin -w print "\n\t\$0 is: " . $0 . "\n\n"; # nikhil.patil's regex $0 =~ /(.*\/)*(.+)/; print "\n\tnikhil.patil's \$2 is: $2\n\n"; print "\n\nww's failed\n\n"; if ( $0 =~ /(?!(.*?)\Q\\\E)\G(.+)$/ ) { print "\n\t \$1 is: |$1|. However, note my failure to capture the +final '\\' in the path\n"; # $path = $1; # print "\n\t\$path is: $path\n"; # BUT HOW DO I CAPTURE THE LAST + "\" IN THE PATH print "\n\t \$2 is: |$2| \n"; print "\n\t \$2 is the whole of \$0 because lookarounds, when comp +leted, discard all intermediate info\n"; } else { print "\n\tNo match\n"; }
        which definitely doesn't do the job:
        ww's failed $1 is: |f:\_wo\pl_test|. However, note my failure to capture +the final '\' in the path $2 is: |f:\_wo\pl_test\669947.pl| $2 is the whole of $0 because lookarounds, when completed, di +scard all intermediate info

        So, using substitution (After Friedl p192)

        $foo = $0; print "\n\t \$foo: |$foo| before the substitution \n"; $foo =~s/^.*\\//; print "\n\t And, after the substitution: |$foo| \n";

        produces this...

        $foo: |f:\_wo\pl_test\669947.pl| before the substitution And, after the substitution: |669947.pl| C:\>

        There are (at least) two morals to this story:

        1. It's easy to build a solution that looks like it works, but isn't general
        2. ww's command of lookarounds needs improvement
      is there a way to extract a file name only (don't include full path) without using additional perl extensions?