in reply to get file name?

$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.

Replies are listed 'Best First'.
Re^2: get file name?
by nikhil.patil (Sexton) on Feb 25, 2008 at 08:47 UTC
    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
        Hi,
        The above RegEx failed on Windows because under Windows the directory delimiter is backslash \. The RegEx was written for Linux where the directory delimiter is forward slash /. For Windows, the RegEx would be:
        $0 =~ /(.*\\)*(.+)/; print $2;
        The following RegEx would work for both Windows and Linux:
        $0 =~ /(.*(\\|\/))*(.+)/; print $3;
Re^2: get file name?
by adrive (Scribe) on Feb 25, 2008 at 08:05 UTC
    is there a way to extract a file name only (don't include full path) without using additional perl extensions?