Created
February 16, 2012 20:47
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 <[email protected]> | |
# | |
# 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