in reply to Re: get file name?
in thread get file name?

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

Replies are listed 'Best First'.
Re^3: get file name?
by hipowls (Curate) on Feb 25, 2008 at 09:28 UTC

    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;

Re^3: get file name?
by ww (Archbishop) on Feb 25, 2008 at 21:30 UTC

    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;