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