Skip to content

Instantly share code, notes, and snippets.

@markusfisch
Created February 16, 2012 20:47
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save markusfisch/1847721 to your computer and use it in GitHub Desktop.
Save markusfisch/1847721 to your computer and use it in GitHub Desktop.
List all files of the given paths sorted by size or time of modification
#!/usr/bin/env perl
#
# latestgreatest - list all files of the given paths sorted by size or
# time of modification
#
# I wrote this for demonstration purposes only.
#
# On a sane system, you should use find instead:
#
# To find files that did change since yesterday:
#
# $ find . -type f -mtime -1
#
# To find files which are greater than 1 Mb:
#
# $ find . -type f -size +1M
#
# If you really want to have a verbose, full listing on a regular basis,
# you may want to put those functions into your .bashrc:
#
# # Find and sort files
# #
# # @param ... - path (optional)
# find_and_sort()
# {
# find $@ -type f -printf "${PREFIX}%h/%f\n" | sort
# }
#
# # Print the latest files
# #
# # @param ... - path (optional)
# latest()
# {
# PREFIX='%TY-%Tm-%Td %TH:%TM ' find_and_sort $@
# }
#
# # Print the greatest files
# #
# # @param ... - path (optional)
# greatest()
# {
# PREFIX='%020s ' find_and_sort $@
# }
#
# Then you can do
#
# $ greatest
#
# Or
#
# $ greatest downloads/ -mtime -1
#
# Well, you got the idea :)
#
# Alas, since -printf is a GNU extension, this does NOT work on BSD
# derivates like OS X.
#
# O ,-
# ° o . -´ ' ,-
# ° .´ ` . ´,´
# ( ° )) . (
# `-;_ . -´ `.`.
# `._' ´
#
# Copyright (c) 2012 Markus Fisch <mf@markusfisch.de>
#
# Licensed under the MIT license:
# http://www.opensource.org/licenses/mit-license.php
#
use strict;
use warnings;
use constant {
SIZE => 7,
MTIME => 9
};
# Walk file hierarchy
#
# @param 1 - path
# @param 2 - true for recursive operation
sub find
{
our @files;
our $sort;
my( $d, $r ) = @_;
my $in;
opendir( $in, $d ) ||
die "error: cannot read directory '$d': $!";
while( my $f = readdir( $in ) )
{
next if $f =~ /^[\.]{1,2}$/;
my $p = "$d/$f";
next if -l $p || -S $p;
if( -d $p )
{
$r && find( $p, $r );
next;
}
my @a = stat( $p );
push( @files, [(int( $a[$sort] ), $p)] );
}
closedir( $in );
}
our @files;
our $sort = SIZE;
# parse arguments and find files
{
my $recursive = 1;
my $find = 0;
foreach my $arg ( @ARGV )
{
if( $arg =~ /^\-/ )
{
my @flags = split( //, $arg );
shift @flags;
foreach my $f ( @flags )
{
if( $f eq 'h' )
{
my $x = $0;
$x =~ s/.*\///;
print <<EOF
usage: $x [-hfsm] [PATH]...
-h show this help
-f do not follow directories
-s sort by file size (default)
-m sort by time of last modification
EOF
;
exit
}
elsif( $f eq 'f' ){ $recursive = 0; }
elsif( $f eq 's' ){ $sort = SIZE; }
elsif( $f eq 'm' ){ $sort = MTIME; }
else{ die "error: unkown flag '$f'" }
}
next;
}
find( $arg, $recursive );
$find = 1;
}
$find || find( '.', $recursive );
}
# print sorted listing of files
for( sort {$a->[0] <=> $b->[0]} ( @files ) )
{
my $s = @$_[0];
if( $sort == MTIME )
{
my( $sec, $min, $hour, $mday,
$mon, $year, $wday, $yday,
$isdst ) = localtime( $s );
$s = sprintf(
"%04d-%02d-%02d %02d:%02d:%02d",
$year+1900,
++$mon,
$mday,
$hour,
$min,
$sec );
}
printf( "%20s %s\n", $s, @$_[1] );
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment