ls /foo/bar/
lrwxr-xr-x a1 -> ../../../a1
lrwxr-xr-x a2 -> ../../../a2
lrwxr-xr-x a3 -> ../../../a3
This is a curtailed output of ls.
My goal: 1. Go to /foo/bar/ and find the latest version of a (which is a symbolic link). So in this case, a3. Copy the contents of a3 to a temp location
I am trying to use File::Find::Rule
but I am unable to figure out how to use it to list all the symbolic links. Reading through various Google sites, I see people explaining how to follow the symbolic links but not to list them.
What I have figured out so far:
my $filePath = "/foo/bar";
my @files = File::Find::Rule->file->in(filePath);
This returns an empty array because there there are no files only symbolic links in /foo/bar.
I also tried
my @files = File::Find::Rule->in($makeFilePath)->extras({follow =>1});
but I feel that is asks to follow the symbolic link rather than list them.
Use the symlink
method from -X test synonyms provided in File::Find::Rule
use warnings 'all';
use strict;
use File::Find::Rule;
my $rule = File::Find::Rule->new;
my @links = $rule->symlink->in('.');
print "@links\n";
This finds all files which satisfy -l
file test in the current directory. Also see -X.
With the list of links on hand, you can use the -M
file test or stat (or its File::stat by-name interface), to sort it out by timestamps of the target files. For example
use List::Util 'max';
my %ts_name = map { (stat)[9] => $_ } @links;
my $latest = $ts_name{ max (keys %ts_name) };
There are other ways to sort/filter/etc a list. If you use -M
then you need min
. If you wanted the timestamps for the link itself for some reason, use the lstat
instead. The module also provides an mtime
method for work with timestamps, but it is meant for search and not suitable for sorting.
Note that you don't have to actually create an object first, but can directly do
use File::Find::Rule;
my @links = File::Find::Rule->symlink->in('.');
To copy/move things use core File::Copy, while for temporary files core File::Temp is useful.