Open Computing ``Hands-On'': ``Wizard's Grabbag'' Column: December 1994: Listings Listing 1: The dateorder script reports files named as month, year (mmmyy) in chronological order. A. Listing of the dateorder Perl program: 1 #! /usr/bin/perl 2 # @(#) dateorder Return mmmyy command-line args in yr, month order. 3 # Author: Robert Nicholson , April 1994 4 # Usage: dateorder mmmyr-string ... 5 6 # Given the following command-line argument list: 7 # INDEX apr90 jan89 dec90 apr89 jan90 dec89 8 # Dateorder returns: 9 # jan89 apr89 dec89 jan90 apr90 dec90 10 11 die "Usage: $0 mmmyr-string [mmmyr-string...]\n" unless @ARGV; 12 %monthorder = 13 ("jan", 1, "feb", 2, "mar", 3, "apr", 4, "may", 5, "jun", 6, 14 "jul", 7, "aug", 8, "sep", 9, "oct", 10, "nov", 11, "dec", 12 ); 15 16 # Only collect arguments with mmmyy (month-year) prefix: 17 $i = 0; # initialize 18 foreach $file (@ARGV) { 19 if (&month_and_year_prefix($file)) { # if proper prefix 20 $monthfiles[$i++]=$file; # save argument 21 } 22 } 23 24 @sorted_months = sort by_date @monthfiles; # order by year, month 25 print "@sorted_months\n"; # space-separated display 26 27 # Comparator to sort by year and then by month in that year: 28 sub by_date { 29 # First three characters are the month string: 30 $amon = substr($a, 0, 3); # mmm saved in amon 31 $bmon = substr($b, 0, 3); # mmm saved in bmon 32 # The next two are the year: 33 $ayr = substr($a, 3, 2); # yy saved in ayr 34 $byr = substr($b, 3, 2); # yy saved in byr 35 36 # Lookup index with lower-case string: 37 $amonthindex = $monthorder{"\L$amon"}; # 1-12 in amonthindex 38 $bmonthindex = $monthorder{"\L$bmon"}; # 1-12 in bmonthindex 39 40 # Catenate the year and adjusted month index: 41 $aall = $ayr.($amonthindex+11); # create four-digit integer 42 $ball = $byr.($bmonthindex+11); # for easy comparision 43 $aall <=> $ball; # by "spaceship" operator 44 } 45 46 # Determine if argument is mmmyy (month and year prefix): 47 sub month_and_year_prefix { 48 local($filename) = @_; 49 50 return 0 if (length($filename) < 5);# files with names too short 51 52 $month = substr($filename,0,3); # save month prefix 53 $year = substr($filename,3,2); # followed by the year 54 55 foreach $key (keys %monthorder) { # for each valid month 56 return 1 if (-f $filename # only consider plain files 57 && $monthorder{$month} # with valid month abbreviation 58 && ($year =~ /\d\d/)) # and two digits for the year 59 } 60 return 0; # not the correct prefix 61 } B. Sample usage: $ echo * dec91.Z index91.Z jan91.Z jul91.Z mar91.Z may91.Z nov91.Z sep91.Z $ dateorder * jan91.Z mar91.Z may91.Z jul91.Z sep91.Z nov91.Z dec91.Z $ {} C. A short simulation using conventional Unix tools, which isn't portable (see text for discussion): $ cd /MirrorFiles/ftp.uu.net/published/unix-world/grabbag $ ls -l 1*/* | sort +0.47 -0.51 +0.52M -rw-r--r-- 1 bne 10451 Feb 20 1994 1990/nov90.Z -rw-r--r-- 1 bne 4100 Feb 20 1994 1994/jan94 -rw-r--r-- 1 bne 9566 Feb 20 1994 1994/feb94 -rw-r--r-- 1 bne 5171 Mar 13 1994 1994/mar94 -rw-r--r-- 1 bne 8271 Apr 6 01:48 1994/apr94 -rw-r--r-- 1 bne 7395 May 24 01:28 1994/may94 -rw-r--r-- 1 bne 16664 May 24 01:28 1994/jun94 -rw-r--r-- 1 bne 4043 Jul 27 01:23 1994/jul94 -rw-r--r-- 1 bne 5429 Jul 30 13:24 1994/aug94 $ {} D. Another simulation command line: $ ls -l 1*/** | \ egrep -i '(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)[0-9][0-9]'| \ sort +0.54n +0.52M Listing 2: Definitions of the directory-climbing functions. A. Listing of the contributed up() function: 1 # @(#) up Move up directory hierarchy specified number of levels 2 # Author: David Wood, March 1990 3 # 4 up() 5 { 6 count=${1:-1} # default one level, otherwise use argument 7 while [ $count -gt 0 ]; do # while need to climb 8 cd .. # go up a level 9 count=`expr $count - 1` # one less level to go 10 done 11 } B. Listing of the version ported to the Korn shell: 1 # @(#) up Move up a directory tree specified number of levels 2 # Author: David Wood, March 1990 3 # Adapted for Korn shell by Becca Thomas, December 1992 4 # 5 function up 6 { 7 Usage="Usage: `basename $0` [level-count]\\nWhere, level-count >0" 8 case $# in 9 0|1) ;; # correct argument count 10 *) print -u2 $Usage; return ;; # no more than one argument 11 esac 12 integer count=${1:-1} # default one level, otherwise use argument 13 if (( $count <= 0 )); then # if argument is not positive 14 print -u2 "level-count must be positive integer\n$Usage";return 15 fi 16 while (( $count -gt 0 )); do # while need to climb 17 cd .. # go up a level 18 let count=count-1 # one less level to go 19 done 20 } Copyright © 1995 The McGraw-Hill Companies, Inc. All Rights Reserved. Edited by Becca Thomas / Online Editor / UnixWorld Online / beccat@wcmh.com [Go to Contents] [Search Editorial] Last Modified: Tuesday, 22-Aug-95 16:18:57 PDT