Recipe 9.10 Splitting a Filename into Its Component Parts

9.10.1 Problem

You want to extract a filename, its enclosing directory, or the extension(s) from a string that contains a full pathname.

9.10.2 Solution

Use routines from the standard File::Basename module.

use File::Basename; $base = basename($path); $dir  = dirname($path); ($base, $dir, $ext) = fileparse($path);

9.10.3 Discussion

The standard File::Basename module contains routines to split up a filename. dirname and basename supply the directory and filename portions, respectively:

$path = "/usr/lib/libc.a"; $file = basename($path);     $dir  = dirname($path);      print "dir is $dir, file is $file\n"; # dir is /usr/lib, file is libc.a

The fileparse function can extract the extension. Pass fileparse the path to decipher and a regular expression that matches the extension. You must supply a pattern because an extension isn't necessarily dot-separated. Consider ".tar.gz": is the extension ".tar", ".gz", or ".tar.gz"? By specifying the pattern, you control which you get.

$path = "/usr/lib/libc.a"; ($name,$dir,$ext) = fileparse($path,'\..*'); print "dir is $dir, name is $name, extension is $ext\n"; # dir is /usr/lib/, name is libc, extension is .a

By default, these routines parse pathnames using your operating system's normal conventions for directory separators by consulting the $^O ($OSNAME) variable, which holds a string identifying the platform you're running on. That value was determined when Perl was built and installed. You can change the default by calling the fileparse_set_fstype routine. This alters the behavior of subsequent calls to the File::Basename functions:

fileparse_set_fstype("MacOS"); $path = "Hard%20Drive:System%20Folder:README.txt"; ($name,$dir,$ext) = fileparse($path,'\..*'); print "dir is $dir, name is $name, extension is $ext\n"; # dir is Hard%20Drive:System%20Folder, name is README, extension is .txt

To pull out just the extension, you might use this:

sub extension {     my $path = shift;     my $ext = (fileparse($path,'\..*'))[2];     $ext =~ s/^\.//;     return $ext; }

When called on a file like source.c.bak, this returns an extension of "c.bak", not just "bak". If you want ".bak" returned, use '\.[^.]*' as the second argument to fileparse (this will, of course, leave the filename as source.c).

When passed a pathname with a trailing directory separator, such as "lib/", fileparse considers the directory name to be "lib/", whereas dirname considers it to be ".".

9.10.4 See Also

The documentation for the standard File::Basename module (also in Chapter 32 of Programming Perl); the entry for $^O ($OSNAME) in perlvar(1), and in the "Special Variables in Alphabetical Order" section of Chapter 28 of Programming Perl



Perl Cookbook
Perl Cookbook, Second Edition
ISBN: 0596003137
EAN: 2147483647
Year: 2003
Pages: 501

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net