NAME

File::Util - Easy, versatile, portable file handling

IMPORTANT!

This is a developer's release, and is not intended for use in the public sector. This code is made available for developers who wish to aid in the furthering of the code, though it _is_ stable.

This is not a registered module in the CPAN module list. It is not part of the CPAN yet.

DESCRIPTION

File::Util provides a comprehensive toolbox of utilities to automate all kinds of common tasks on file / directories. Its purpose is to do so in the most portable manner possible so that users of this module won't have to worry about whether their programs will work on other OSes and machines.

SYNOPSIS

use File::Util;
my($f) = File::Util->new();

my($content) = $f->load_file('foo.txt');

$content =~ s/this/that/g;

$f->write_file(
   'file' => 'bar.txt,
   'content' => $content,
   'bitmask' => 0644
);

my(@lines) = $f->load_file('randomquote.txt', '--as-lines');
my($line)  = int(rand(scalar @lines));

print $lines[$line];

my(@files) = $f->list_dir('/var/tmp', qw/ --files-only --recurse /);

if ($f->can_write('wibble.log')) {

   my($HANDLE) = $f->open_handle(
      'file' => 'wibble.log',
      'mode' => 'append'
   );

   print $HANDLE "Hello World! It's ", scalar localtime;

   close $HANDLE
}

my($log_line_count) = $f->line_count('/var/log/httpd/access_log');

print "My file has a bitmask of " . $f->bitmask('my.file');

# ...and _lots_ more

INSTALLATION

To install this module type the following at the command prompt:

perl Makefile.PL
make
make test
make install

On windows machines use nmake rather than make; those running cygwin don't have to worry about this. If you don't know what cygwin is, use nmake and check out http://cygwin.com/ after you're done installing this module if you want to find out.

ISA

Exporter
Class::OOorNO

EXPORTED SYMBOLS

Exports nothing by default.

EXPORT_OK

The following symbols comprise @File::Util::EXPORT_OK), and as such are available for import to your namespace only upon request.

bitmask (see bitmask)

can_flock (see can_flock)

can_read (see can_read)

can_write (see can_write)

created (see created)

ebcdic (see ebcdic)

escape_filename (see escape_filename)

existent (see existent)

file_type (see file_type)

isbin (see isbin)

last_access (see last_access)

last_modified (see last_modified)

NL (see NL)

needs_binmode (see needs_binmode)

return_path (see return_path)

size (see size)

SL (see SL)

strip_path (see strip_path)

valid_filename (see valid_filename)

Note: Symbols in @Class::OOorNO::EXPORT_OK are also available for import.

EXPORT_TAGS

:all (exports all of @File::Util::EXPORT_OK)

METHODS

Note: Some of the methods listed will state that they are autoloaded methods. Autloaded methods are not compiled at runtime as part of your process and only get created if called somewhere in your program. (see AutoLoader.)

Methods listed in alphabetical order.

bitmask

Syntax: bitmask( [file name] )

Gets the bitmask of the named file, provided the file exists. If the file exists, the bitmask of the named file is returned in four digit octal notation eg- 0644. Otherwise, returns undef if the file does not exist. This is an autoloaded method.

can_flock

Syntax: can_flock

Returns 1 if the current system claims to support flock() and if the Perl process can successfully call it. (see "flock" in perlfunc.) Unless both of these conditions are true a zero value (0) is returned. This is an autoloaded method. This is a constant subroutine. It accepts no arguments and will always return the same value for the system on which it is executed.

Note: Perl will try to support or emulate flock whenever it can via available system calls, namely flock; lockf; or with fcntl.

can_read

Syntax: can_read( [file name] )

Returns 1 if the named file (or directory) is readable by your program according to the applied permissions of the file system on which the file resides. Otherwise a value of undef is returned.

This works the same as Perl's built-in -r file test operator, (see "-X" in perlfunc), it's just easier for some people to remember. This is an autoloaded method.

can_write

Syntax: can_write( [file name] )

Returns 1 if the named file (or directory) is writable by your program according to the applied permissions of the file system on which the file resides. Otherwise a value of undef is returned.

This works the same as Perl's built-in -w file test operator, (see "-X" in perlfunc), it's just easier for some people to remember. This is an autoloaded method.

created

Syntax: created( [file name] )

Returns the time of creation for the named file in non-leap seconds since whatever your system considers to be the epoch. Suitable for feeding to Perl's built-in functions "gmtime" and "localtime". (see "time" in perlfunc.) This is an autoloaded method.

ebcdic

Syntax: ebcdic

Returns 1 if the machine on which the code is running uses EBCDIC, or returns 0 if not. (see perlebcdic.) This is an autoloaded method. This is a constant subroutine. It accepts no arguments and will always return the same value for the system on which it is executed.

escape_filename

Syntax: escape_filename( [string], [escape char] )

Returns it's argument in an escaped form that is suitable for use as a filename. Illegal characters (i.e.- any type of newline character, tab, vtab, and the following / | * " ? < : \>), are replaced with [escape char] or "_" if no [escape char] is specified. Returns an empty string if no arguments are provided. This is an autoloaded method.

existent

Syntax: existent( [file name] )

Returns 1 if the named file (or directory) exists. Otherwise a value of undef is returned.

This works the same as Perl's built-in -e file test operator, (see "-X" in perlfunc), it's just easier for some people to remember. This is an autoloaded method.

file_type

Syntax: file_type( [file name] )

Returns a list of keywords corresponding to each of Perl's built in file tests (those specific to file types) for which the named file returns true. (see "-X" in perlfunc.) This is an autoloaded method.

The keywords and their definitions appear below; the order of keywords returned is the same as the order in which the are listed here:

PLAIN File is a plain file.
TEXT File is a text file.
BINARY File is a binary file.
DIRECTORY File is a directory.
PIPE File is a named pipe (FIFO).
SOCKET File is a socket.
BLOCK File is a block special file.
CHARACTER File is a character special file.

flock_rules

Syntax: flock_rules( [keyword list] )

Sets I/O race condition policy, or tells File::Util how it should handle race conditions created when a file can't be locked because it is already locked somewhere else (usually by another process).

An empty call to this method returns a list of keywords representing the rules that are currently in effect for the object.

Otherwise, a call should include a list with array containing your chosen directive keywords in order of precedence. The rules will be applied in cascading order when a File::Util object attempts to lock a file, so if the actions specified by the first rule don't result in success, the second rule is applied, and so on.

Recognized keywords:

NOBLOCKEX

tries to get an exclusive lock on the file without blocking (waiting)

NOBLOCKSH

tries to get a shared lock on the file without blocking

BLOCKEX

waits to try getting an exclusive lock

BLOCKSH

waits to try getting a shared lock

FAIL

dies with stack trace

WARN

warn()s about the error with a stack trace and returns undef

IGNORE

ignores the failure to get an exclusive lock

UNDEF

returns undef

ZERO

returns 0

Examples:

ex- flock_rules( qw/ NOBLOCKEX FAIL / );

This is the default policy. When in effect, the File::Util object will first attempt to get a non-blocking exclusive lock on the file. If that attempt fails the File::Util object will call die() with a detailed error message and a stack trace.

ex- flock_rules( qw/ NOBLOCKEX BLOCKEX FAIL / );

The File::Util object will first attempt to get a non-blocking exclusive lock on the file. If that attempt fails it falls back to the second policy rule "BLOCKEX" and tries again to get an exclusive lock on the file, but this time by blocking (waiting for its turn). If that second attempt fails, the File::Util object will fail with a detailed error message and a stack trace.

ex- flock_rules( qw/ BLOCKEX IGNORE / );

The File::Util object will first attempt to get a file non-blocking lock on the file. If that attempt fails it will ignore the error, and go on to open the file anyway and no failures will occur or warings be issued.

This is an autoloaded method.

isbin

Syntax: isbin( [file name] )

Returns 1 if the named file (or directory) exists. Otherwise a value of undef is returned, indicating that the named file either does not exist or is of another file type.

This works the same as Perl's built-in -B file test operator, (see "-X" in perlfunc), it's just easier for some people to remember. This is an autoloaded method.

last_access

Syntax: last_access( [file name] )

Returns the last accessed time for the named file in non-leap seconds since whatever your system considers to be the epoch. Suitable for feeding to Perl's built-in functions "gmtime" and "localtime". (see "time" in perlfunc.) This is an autoloaded method.

last_modified

Syntax: last_modified( [file name] )

Returns the last modified time for the named file in non-leap seconds since whatever your system considers to be the epoch. Suitable for feeding to Perl's built-in functions "gmtime" and "localtime". (see "time" in perlfunc.) This is an autoloaded method.

line_count

Syntax: line_count( [file name] )

Returns the number of lines in the named file. Fails with an error if the named file does not exist.

list_dir

Syntax: list_dir( [directory name] , [--opts] )

Returns alphabetically sorted all file names in the directory specified if it exists. Fails with an error message if no such directory is found.

Flags accepted by list_dir()
--dirs-only

return only directory contents which are directories

--files-only

return only directory contents which are files

--no-fsdots

do not include "." and ".." in the list of directory contents

--pattern

return only files/directories matching pattern provided. argument should be plain text string. It will be converted to a perl regex and passed to CORE::grep as the method scans through directory listings for a match.

(ex- --pattern='\.txt$' returns all file/directory names ending in ".txt". It will match "foo.txt", but not "foo.txt.gz" because of the "$" anchor in the regular expression passed in.)

--with-paths

Include file paths with the contents of the directory list, relative to the directory named in the call.

--recurse

Recurse subdirectories

--follow

Recurse subdirectories, same as --recurse

--dirs-as-ref

When returning directory listing, include first a reference to the list of subdirectories found, followed by anything else returned by the call.

--files-as-ref

When returning directory listing, include last a reference to the list of files found, preceded by a list of subdirectories found (or preceeded by a list reference to subdirectories found if --dirs-as-ref was also used).

--as-ref

Return a pair list references: the first is a reference to any subdirectories found by the call, the second is a reference to any files found by the call.

--sl-after-dirs

Append a directory seperator ("/, "\", or ":" depending on your system) to all directories found by the call. Useful in visual displays for quick differentiation between subdirectories and files.

--ignore-case

Items returned by the call to this method are sorted alphabetically by default, so "Zoo.txt" comes before "alligator.txt" because the alphabetical sort is case-sensitive. This is also the way directories are listed at the system level on most operating systems.

If you'd like the directory contents returned by this method to be sorted without regard to case , use this flag.

--count-only

Returns a single value: an integer reflecting the number of items found in the directory after applying the filter criteria specified by any other flags (ie- "--dirs-only", "--recurse", etc.) that may have been passed in as well.

load_dir

Syntax: load_dir( [directory name] , [--ds-type] )

Returns a data structure containing the contents of each file present in the named directory. This is an autoloaded method.

The type of data structure returned is determined by the optional data-type switch. Only one option may be used for a given call to this method. Recognized options are listed below.

--as-list

Causes the method to return a list comprised of the contents loaded from each file (in case-sensitive order) located in the named directory.

--as-listref

Same as above, except an array reference to the list of items is returned rather than the list itself.

--as-hashref *(default)

Implicit. If no option is passed in, the default behavior is to return a reference to an anonymous hash whose keys are the names of each file in the specified directory; the hash values for contain the contents of the file represented by its corresponding key.

Note: This method does not distinguish between plain files and other file types such as binaries, FIFOs, sockets, etc.

Restrictions imposed by the current "read limit" (see the readlimit()) entry below will be applied to the files opened by this method as well. Adjust the readlimit as necessary.

my($files) = $fu->load_dir('directory/to/load/');

The above code creates an anonymous hash reference that is stored in the variable named "$files". The keys and values of the hash referenced by "$files" would resemble those of the following code snippet (given that the files in the named directory were the files 'a.txt', 'b.html', 'c.dat', and 'd.conf')

my($files) =
   {
      'a.txt'  => "the contents of file a.txt",
      'b.html' => "the contents of file b.html",
      'c.dat'  => "the contents of file c.dat",
      'd.conf' => "the contents of file d.conf",
   };

load_file

Syntax: load_file( [file name] , [--opts] )

-- Documentation for this method is not yet complete! --

make_dir

Syntax: make_dir( [new directory name] , [--opts] )

-- Documentation for this method is not yet complete! --

This is an autoloaded method.

max_dives

Syntax: max_dives( [integer] )

When called without any arguments, this method returns an integer reflecting the current number of times the File::Util object will dive into the subdirectories it discovers when recursively listing directory contents from a call to File::Util::list_dir(). The default is 1000. If the number is exceeded, the File::Util object will fail with a diagnostic error message.

When called with an argument, it sets the maximum number of times a File::Util object will recurse into subdirectories before failing with an error message.

This method can only be called with a numeric integer value. Passing a bad argument to this method will cause it to fail with an error message.

(see list_dir)

This is an autoloaded method.

needs_binmode

Syntax: needs_binmode

Returns 1 if the machine on which the code is running requires that binmode() (a built-in function) be called on open file handles, or returns 0 if not. (see "binmode" in perlfunc.) This is an autoloaded method. This is a constant subroutine. It accepts no arguments and will always return the same value for the system on which it is executed.

new

Syntax: new( ['parameters' = 'values', etc], [--flags] )>

This is the File::Util constructor method. eg- It returns a new File::Util object reference when you call it. It recognizes various parameters and flags that govern the behavior of the new File::Util object.

Parameters accepted by new()
use_flock => true/false value

Optionally specify this option to the File::Util::new method instruct the new object that it should never attempt to use flock() in it's I/O operations. The default is to use flock() when available on your system. Specify this option with a true or false value, true to use flock(), false to not use it.

readlimit => positive integer

Optionally specify this option to the File::Util::new method to instruct the new object that it should never attempt to open and read in a file greater than the number of bytes you specify. Obviously this argument can only be a numeric integer value, otherwise it will be silently ignored. The default readlimit for File::Util objects is 1,048,576 bytes (10 megabytes).

max_dives => positive integer

Optionally specify this option to the File::Util::new method to instruct the new object to set the maximum number of times it will recurse into subdirectories while performing directory listing operations before failing with an error message. This argument can only be a numeric integer value, otherwise it will be silently ignored.

Flags accepted by new()
--fatals-as-warning

Directive to instruct the new File::Util object that when any call to one of its methods results in a fatal error that it should return undef instead of the value(s) that would normally be returned by the call, and to send an error message to STDERR as well.

--fatals-as-status

Directive to instruct the new File::Util object that when any call to one of its methods results in a fatal error that it should return undef instead of the value(s) that would normally be returned by the call.

--fatals-as-errmsg

Directive to instruct the new File::Util object that when any call to one of its methods results in a fatal error that it should return an error message instead of the value(s) that would normally be returned by the call.

open_handle

Syntax: open_handle( [file name] , [--opts] )

-- Documentation for this method is not yet complete! --

This is an autoloaded method.

readlimit

Syntax: readlimit( [integer] )

-- Documentation for this method is not yet complete! --

This is an autoloaded method.

return_path

Syntax: return_path( [string] )

Takes the file path from the file name provided and returns it such that "/foo/bar/baz.txt" is returned "baz.txt".

This is an autoloaded method.

size

Syntax: size( [file name] )

-- Documentation for this method is not yet complete! --

This is an autoloaded method.

strip_path

Syntax: strip_path( [string] )

Strips the file path from the file name provided and returns the file name only.

trunc

Syntax: trunc( [file name] )

-- Documentation for this method is not yet complete! --

This is an autoloaded method.

use_flock

Syntax: use_flock( [true / false value] )

When called without any arguments, this method returns a true or false value to reflect the current use of flock() within the File::Util object.

When called with a true or false value as its single argument, this method will tell the File::Util object whether or not it should attempt to use flock() in its I/O operations. A true value indicates that the File::Util object will use flock() if available, a false value indicates that it will not. The default is to use flock() when available on your system.

This is an autoloaded method.

write_file

Syntax: write_file('file' => [file name], 'content' => [data], [--opts])

-- Documentation for this method is not yet complete! --

valid_filename

Syntax: valid_filename( [string] )

For the given string, returns 1 if the string is a legal file name for the system on which the program is running, or returns undef if it is not. This method does not test for the validity of file paths! It tests for the validity of file names only. (It is used internally to check beforehand if a file name is useable when creating new files, but is also a public method available for external use.)

CONSTANTS

NL

Syntax: NL

Returns the correct new line character (or character sequence) for the system on which your program runs.

SL

Syntax: SL

Returns the correct directory path seperator for the system on which your program runs.

This is a constant.

PREREQUISITES

Perl 5.006 or better
Class::OOorNO v0.01_1 or better
Exception::Handler v1.00_0 or better

EXAMPLES

Get the names of all files and subdirectories in a directory

use File::Util;
my($f) = File::Util->new();
# option --no-fsdots excludes "." and ".." from the list
my(@dirs_and_files) = $f->list_dir('/foo','--no-fsdots');

Get the names of all files and subdirectories in a directory, recursively

use File::Util;
my($f) = File::Util->new();
my(@dirs_and_files) = $f->list_dir('/foo','--recurse');

Get the names of all files (no subdirectories) in a directory

use File::Util;
my($f) = File::Util->new();
my(@dirs_and_files) = $f->list_dir('/foo','--files-only');

Get the names of all subdirectories (no files) in a directory

use File::Util;
my($f) = File::Util->new();
my(@dirs_and_files) = $f->list_dir('/foo','--dirs-only');

Get the number of files and subdirectories in a directory

use File::Util;
my($f) = File::Util->new();
my(@dirs_and_files) = $f->list_dir('/foo', qw/--no-fsdots --count-only/);

Get the names of files and subdirs in a directory as seperate array refs

use File::Util;
my($f) = File::Util->new();
my($dirs,$files) = $f->list_dir('/foo', '--as-ref');

   -OR-
my($dirs,$files) = $f->list_dir('.', qw/--dirs-as-ref --files-as-ref/);

Get the contents of a file in a string

use File::Util;
my($f) = File::Util->new();
my($contents) = $f->load_file('filename');

Get the contents of a file in an array of lines in the file

use File::Util;
my($f) = File::Util->new();
my(@contents) = $f->load_file('filename','--as-lines');

Get an open file handle for reading

use File::Util;
my($f) = File::Util->new();
my($FH_REF) = $f->open_handle(
   'file' => 'new_filename',
   'mode' => 'read'
);

Get an open file handle for writing

use File::Util;
my($f) = File::Util->new();
my($FH_REF) = $f->open_handle(
   'file' => 'new_filename',
   'mode' => 'write'
);

Write to a new or existing file

use File::Util;
my($content) = 'Pathelogically Eclectic Rubbish Lister';
my($f) = File::Util->new();
$f->write_file('file' => 'a new file.txt', 'content' => $content);

# optionally specify a creation bitmask when writing to a new file
$f->write_file(
   'file'    => 'a new file.txt',
   'bitmask' => 0777,
   'content' => $content
);

Append to a new or existing file

use File::Util;
my($content) = 'Pathelogically Eclectic Rubbish Lister';
my($f) = File::Util->new();
$f->write_file(
   'file' => 'a new file.txt',
   'mode' => 'append',
   'content' => $content
);

Determine if something is a valid file name

use File::Util qw( valid_filename );

if (valid_filename("foo?+/bar~@/#baz.txt")) {
   print "file name is valid"
else {
   print "file name contains illegal characters"
}

   -OR-
use File::Util;
print File::Util->valid_filename("foo?+/bar~@/#baz.txt") ? 'ok' : 'bad';

   -OR-
use File::Util;
my($f) = File::Util->new();
print $f->valid_filename("foo?+/bar~@/#baz.txt") ? 'ok' : 'bad';

Get the number of lines in a file

use File::Util;
my($f) = File::Util->new();
my($linecount) = $f->line_count('foo.txt');

Strip the path from a file name

use File::Util;
my($f) = File::Util->new();

# On Windows
#  (prints "hosts")
my($path) = $f->strip_path('C:\WINDOWS\system32\drivers\etc\hosts');

# On Linux/Unix
#  (prints "perl")
print $f->strip_path('/usr/bin/perl');

# On a Mac
#  (prints "baz")
print $f->strip_path('foo:bar:baz');

Get the path preceeding a file name

use File::Util;
my($f) = File::Util->new();

# On Windows
#  (prints "C:\WINDOWS\system32\drivers\etc")
my($path) = $f->strip_path('C:\WINDOWS\system32\drivers\etc\hosts');

# On Linux/Unix
#  (prints "/usr/bin")
print $f->strip_path('/usr/bin/perl');

# On a Mac
#  (prints "foo:bar")
print $f->strip_path('foo:bar:baz');

Find out if the host system can use flock

use File::Util qw( can_flock );
print can_flock;

   -OR-
print File::Util->can_flock;

   -OR-
my($f) = File::Util->new();
print $f->can_flock;

Find out if the host system needs to call binmode on binary files

use File::Util qw( needs_binmode );
print needs_binmode;

   -OR-
use File::Util;
print File::Util->needs_binmode;

   -OR-
use File::Util;
my($f) = File::Util->new();
print $f->needs_binmode;

Find out if a file can be opened for read (based on file permissions)

use File::Util;
my($f) = File::Util->new();
my($is_readable) = $f->can_read('foo.txt');

Find out if a file can be opened for write (based on file permissions)

use File::Util;
my($f) = File::Util->new();
my($is_writable) = $f->can_write('foo.txt');

Escape illegal characters in a potential file name (and its path)

use File::Util;
my($f) = File::Util->new();

# prints "C__WINDOWS_system32_drivers_etc_hosts"
print $f->escape_filename('C:\WINDOWS\system32\drivers\etc\hosts');

# prints "baz)__@^"
# (strips the file path from the file name, then escapes it
print $f->escape_filename(
   '/foo/bar/baz)?*@^',
   '--strip-path'
);

# prints "_foo_!_@so~me#illegal$_file&(name"
# (yes, that is a legal filename)
print $f->escape_filename(q[\foo*!_@so~me#illegal$*file&(name]);

Find out if the host system uses EBCDIC

use File::Util qw( ebcdic );
print ebcdic;

   -OR-
use File::Util;
print File::Util->ebcdic;

   -OR-
use File::Util;
my($f) = File::Util->new();
print $f->ebcdic;

Get the type(s) of an existent file

use File::Util qw( file_type );
print file_type('foo.exe');

   -OR-
use File::Util;
print File::Util->file_type('bar.txt');

   -OR-
use File::Util;
my($f) = File::Util->new();
print $f->file_type('/dev/null');

Get the bitmask of an existent file

use File::Util qw( bitmask );
print bitmask('/usr/sbin/sendmail');

   -OR-
use File::Util;
print File::Util->bitmask('C:\COMMAND.COM');

   -OR-
use File::Util;
my($f) = File::Util->new();
print $f->bitmask('/dev/null');

Get time of creation for a file

use File::Util qw( created );
# prints "Fri Aug 22 14:57:58 2003" on my system
print scalar localtime created('/usr/bin/exim');

   -OR-
use File::Util;
# prints "Fri Apr 23 22:22:00 1999" on my system
print scalar localtime File::Util->created('C:\COMMAND.COM');

   -OR-
use File::Util;
my($f) = File::Util->new();
# prints "Thu Jul 24 05:51:30 2003" on my system
print scalar localtime $f->created('/bin/less');

Get the last access time for a file

use File::Util qw( last_access );
# prints "Fri Sep  5 04:11:41 2003" on my system
print scalar localtime last_access('/usr/bin/exim');

   -OR-
use File::Util;
# prints "Mon Sep 22 18:51:53 2003" on my system
print scalar localtime File::Util->last_access('C:\COMMAND.COM');

   -OR-
use File::Util;
my($f) = File::Util->new();
# prints "Mon Sep 22 03:14:38 2003" on my system
print scalar localtime $f->last_access('/bin/less');

Get the last modified time for a file

use File::Util qw( last_modified );
# prints "Fri Sep  5 01:14:51 2003" on my system
print scalar localtime last_modified('/usr/bin/exim');

   -OR-
use File::Util;
# prints "Fri Apr 23 22:22:00 1999" on my system
print scalar localtime File::Util->last_modified('C:\COMMAND.COM');

   -OR-
use File::Util;
my($f) = File::Util->new();
# prints "Fri Sep  5 01:15:17 2003" on my system
print scalar localtime $f->last_modified('/bin/less');

Make a new directory, recursively if neccessary

use File::Util;
my($f) = File::Util->new();
$f->make_dir('/var/tmp/tempfiles/foo/bar/');

# optionally specify a creation bitmask to be used in directory creations
$f->make_dir('/var/tmp/tempfiles/foo/bar/',0755);

Truncate a file

use File::Util;
my($f) = File::Util->new();
$f->trunc('/foo/bar/baz.tmp');

Get the correct path seperator for the host system

use File::Util qw( SL );
print SL;

   -OR-
use File::Util;
print File::Util->SL;

   -OR-
use File::Util;
my($f) = File::Util->new();
print $f->SL;

Get the correct newline character for the host system

use File::Util qw( NL );
print NL;

   -OR-
use File::Util;
print File::Util->NL;

   -OR-
use File::Util;
my($f) = File::Util->new();
print $f->NL;

EXAMPLES (Full Programs)

Batch File Rename

# Code changes the file suffix of all files in a directory ending in
# *.foo so that they afterward end in *.bar

use strict;
use vars qw( $dir );
use File::Util qw( NL SL );

my($f)      = File::Util->new();
my($dir)    = '../wibble';
my($old)    = 'foo';
my($new)    = 'bar';
my(@files)  = $f->list_dir($dir, '--files-only');

foreach (@files) {

   # don't change the file suffix unless it is *.foo
   if ($_ =~ /\.$old$/o) {

      my($newname) = $_; $newname =~ s/\.$old/\.$new/;

      if (rename($dir . SL . $_, $dir . SL . $newname)) {

         print qq[$_ -> $newname], NL
      }
      else { warn <<__ERR__ }
Couldn't rename "$_" to "$newname"!
__ERR__
   }
   else { print <<__NOCHANGE__ }
File retained as "$_"
__NOCHANGE__
}

Batch Search & Replace

# Code does a batch find or search and replace for all files in a given
# directory, recursively or non-recursively based on choices set forth
# in the code.

use strict;
use File::Util qw( NL SL );

# will get search pattern from file named below
use constant SFILE => './sr/searchfor';

# will get replace pattern from file named below
use constant RFILE => './sr/replacewith';

# will perform batch operation in directory named below
use constant INDIR => '/foo/bar/baz';

# specify whether the operation will do a find or a search and replace
use constant RMODE => [qw| read-only  write |]->[1];

# set the options for the search (will or will not recurse, etc)
my(@opts) = [qw/ --files-only --with-paths --recurse /]->[0,1];

# create new File::Util object, set File::Util to send a warning for
# fatal errors instead of dieing
my($f)         = File::Util->new('--fatals-as-warning');
my($rstr)      = $f->load_file(RFILE);
my($spat)      = quotemeta($f->load_file(SFILE)); $spat = qr/$spat/;
my($gsbt)      = 0;
my($action)    = RMODE eq 'read-only' ? 'detections' : 'substitutions';
my(@files)     = $f->list_dir(INDIR, @opts);

for (my($i) = 0; $i < @files; ++$i) {

   next if $f->isbin($files[$i]);

   my($sbt) = 0; my($file) = $f->load_file($files[$i]);

   $file =~ s/$spat/++$sbt;++$gsbt;$rstr/ge;

   $f->write_file('file' => $files[$i], 'content' => $file)
      if RMODE eq 'write';

   print $sbt ? (qq[$sbt $action in $files[$i]] . NL) : '';
}

print( NL . <<__DONE__ . NL x 2) and exit;
$gsbt $action in ${\scalar(@files)} files.
__DONE__

Pretty-Print A Directory Recursively

use strict;
use vars qw( $a $b );

use File::Util qw( NL );
my($ind) = '';
my($f)   = File::Util->new();
my(@o)   = qw(
   --with-paths
   --sl-after-dirs
   --no-fsdots
   --files-as-ref
   --dirs-as-ref
);

my($filetree)  = {};
my($treetrunk) = '/var/';
my($subdirs,$sfiles) = $f->list_dir($treetrunk, @o);

$filetree = [{
   $treetrunk => [ sort({ uc $a cmp uc $b } @$subdirs, @$sfiles) ]
}];

descend($filetree->[0]{ $treetrunk },scalar(@$subdirs));
walk(@$filetree);

sub descend {
   my($parent,$dirnum) = @_;
   for (my($i) = 0; $i < $dirnum; ++$i) {
      my($current) = $parent->[$i]; next unless -d $current;
      my($subdirs,$sfiles) = $f->list_dir($current, @o);
      map { $_ = $f->strip_path($_) } @$sfiles;
      splice(@$parent,$i,1,{
         $current => [ sort({ uc $a cmp uc $b } @$subdirs, @$sfiles) ]
      });
      descend($parent->[$i]{ $current },scalar(@$subdirs));
   }
   $parent
}

sub walk {
   my($dir) = shift(@_);
   foreach (@{ [ %$dir ]->[1] }) {
      my($mem) = $_;
      if (ref($mem) eq 'HASH') {
         print($ind . $f->strip_path([ %$mem ]->[0]) . '/',NL);
         $ind .= ' ' x 3;
         walk($mem);
         $ind = substr($ind,3);
      } else { print($ind . $mem,NL) }
   }
}

BUGS

This documentation isn't done yet, as you can see. This is being rectified as quickly as possible. Please exercise caution if you choose to use this code before it can be further documented for you. Please excuse the inconvenience.

AUTHOR

Tommy Butler <cpan@atrixnet.com>

COPYRIGHT

Copyright(C) 2001-2003, Tommy Butler. All rights reserved.

LICENSE

This library is free software, you may redistribute and/or modify it under the same terms as Perl itself.

SEE ALSO

File::Slurp, Exception::Handler, Class::OOorNO