#!/bin/perl -w eval 'exec /usr/bin/perl -S $0 ${1+"$@"}' if 0; #$running_under_some_shell use strict; use File::Find (); =head1 NAME newest - find newest files in a directory tree =head1 SYNOPSIS newest [-a] [-N] directory... =head1 DESCRIPTION Find the N newest files from the directories provided. Option -a also searches hidden directories. Very simple and short program. =head1 NOTES Only works on Unix. =head1 SEE ALSO L, L =cut # Set the variable $File::Find::dont_use_nlink if you're using AFS, # since AFS cheats. # for the convenience of &wanted calls, including -eval statements: use vars qw/*name *dir *prune/; *name = *File::Find::name; *dir = *File::Find::dir; *prune = *File::Find::prune; my @rwx = qw(--- --x -w- -wx r-- r-x rw- rwx); my @moname = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec); my (%uid, %user); while (my ($name, $pw, $uid) = getpwent) { $user{$uid} = $name unless exists $user{$uid}; } my (%gid, %group); while (my ($name, $pw, $gid) = getgrent) { $group{$gid} = $name unless exists $group{$gid}; } # array of files my @suite = (); # files found my @start= (); # directories to start from my $ssize = 0; # max size of suite my $all = 0; # include .* patterns my $errs = 0; # arg errors sub do_sort {@suite = sort { $b->[1] <=> $a->[1]; } @suite;} while ($_ = shift) { if ($ssize == 0 && /-[0-9]+$/) { $ssize = -$_; } elsif (/-a/) { $all = 1; } elsif (-d) { push @start, $_; } else { ++$errs; print "$_ is not a directory\n"; } } die unless $errs == 0; $ssize = 8 if $ssize <= 0; # Traverse desired filesystems (follow_fast => 1,)? File::Find::find( {wanted => \&wanted, no_chdir => 0}, @start); &do_sort if $ssize > @suite; &report; exit; sub wanted { if ($all == 0 && /^\..+/) { $File::Find::prune = 1; return; } my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size, $atime,$mtime,$ctime,$blksize,$blocks) = lstat($_); return if ! -f _ || $ssize <= @suite && $suite[$ssize-1]->[1] > $mtime; my @file = ($File::Find::name, $mtime); if ($ssize > @suite) { &do_sort if (push(@suite, \@file) >= $ssize); return; } my $i; for ($i = 0; $i < @suite; ++$i) { my $t = $suite[$i]->[1]; if ($t < $mtime) { splice(@suite, $i, 0, \@file); pop(@suite); last; } } } sub report { my ($dev,$ino,$mode,$nlink,$uid,$gid); my $name; foreach (@suite) { my $name = $_->[0]; ($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($name); &ls($name); } } sub sizemm { my $rdev = shift; sprintf("%3d, %3d", ($rdev >> 8) & 0xff, $rdev & 0xff); } sub ls { my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size, $atime,$mtime,$ctime,$blksize,$blocks) = lstat(_); my $pname = shift; $blocks or $blocks = int(($size + 1023) / 1024); my $perms = $rwx[$mode & 7]; $mode >>= 3; $perms = $rwx[$mode & 7] . $perms; $mode >>= 3; $perms = $rwx[$mode & 7] . $perms; substr($perms, 2, 1) =~ tr/-x/Ss/ if -u _; substr($perms, 5, 1) =~ tr/-x/Ss/ if -g _; substr($perms, 8, 1) =~ tr/-x/Tt/ if -k _; if (-f _) { $perms = '-' . $perms; } elsif (-d _) { $perms = 'd' . $perms; } elsif (-l _) { $perms = 'l' . $perms; $pname .= ' -> ' . readlink($_); } elsif (-c _) { $perms = 'c' . $perms; $size = sizemm($rdev); } elsif (-b _) { $perms = 'b' . $perms; $size = sizemm($rdev); } elsif (-p _) { $perms = 'p' . $perms; } elsif (-S _) { $perms = 's' . $perms; } else { $perms = '?' . $perms; } my $user = $user{$uid} || $uid; my $group = $group{$gid} || $gid; my ($sec,$min,$hour,$mday,$mon,$timeyear) = localtime($mtime); printf "%-10s %3d %-8s %-8s %8.2fk %5s %s %2d %02d:%02d:%02d %s\n", $perms, $nlink, $user, $group, $size/1024, $timeyear + 1900, $moname[$mon], $mday, $hour, $min, $sec, $pname; # if (-M _ > 365.25 / 2) { # $timeyear += 1900; # } else { # $timeyear = sprintf("%02d:%02d", $hour, $min); # } # # printf "%5lu %4ld %-10s %3d %-8s %-8s %8s %s %2d %5s %s\n", # $ino, # $blocks, # $perms, # $nlink, # $user, # $group, # $size, # $moname[$mon], # $mday, # $timeyear, # $pname; 1; }