start page | rating of books | rating of authors | reviews | copyrights

Perl Cookbook

Perl CookbookSearch this book
Previous: 9.3. Copying or Moving a File Chapter 9
Directories
Next: 9.5. Processing All Files in a Directory
 

9.4. Recognizing Two Names for the Same File

Problem

You want to identify if two filenames in a list correspond to the same file on disk (because of hard and soft links, two filenames can refer to a single file). You might do this to make sure that you don't change a file you've already worked with.

Solution

Maintain a hash, keyed by the device and inode number of the files you've seen. The values are the names of the files:

%seen = ();  sub do_my_thing {     my $filename = shift;     my ($dev, $ino) = stat $filename;      unless ($seen{$dev, $ino}++) {         # do something with $filename because we haven't         # seen it before     } }

Discussion

A key in %seen is made by combining the device number ( $dev ) and inode number ( $ino ) of each file. Files that are the same will have the same device and inode numbers, so they will have the same key.

If you want to maintain a list of all files of the same name, instead of counting the number of times seen, save the name of the file in an anonymous array.

foreach $filename (@files) {     ($dev, $ino) = stat $filename;     push( @{ $seen{$dev,$ino} }, $filename); }  foreach $devino (sort keys %seen) {     ($dev, $ino) = split(/$;/o, $devino);     if (@{$seen{$devino}} > 1) {         # @{$seen{$devino}} is a list of filenames for the same file     } }

The $; variable contains the separator string using the old multidimensional associative array emulation syntax, $hash{$x,$y,$z} . It's still a one-dimensional hash, but it has composite keys. The key is really join($; => $x, $y, $z) . The split separates them again. Although you'd normally just use a real multilevel hash directly, here there's no need, and it's cheaper not to.

See Also

The $; variable in perlvar (1), and in the "Special Variables" section of Chapter 2 of Programming Perl ; the stat function in perlfunc (1) and in Chapter 3 of Programming Perl ; Chapter 5, Hashes


Previous: 9.3. Copying or Moving a File Perl Cookbook Next: 9.5. Processing All Files in a Directory
9.3. Copying or Moving a File Book Index 9.5. Processing All Files in a Directory