home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2759 < prev    next >
Encoding:
Internet Message Format  |  1991-02-15  |  4.3 KB

  1. From: alfie@cs.warwick.ac.uk (Nick Holloway)
  2. Newsgroups: alt.sources,comp.lang.perl
  3. Subject: Perl script to reverse the order of lines.
  4. Message-ID: <*||&R~@warwick.ac.uk>
  5. Date: 14 Feb 91 16:49:20 GMT
  6.  
  7. The included script reversing the order of lines in a file.  Unlike
  8. 'rev' which reverses the characters in each line, 'reverse' will
  9. reverse the order of the lines.  Think of it as reversal in the other
  10. dimension!  The usage is "reverse [ file ... ]"
  11.  
  12. The script is for you to do with as you please, though I would
  13. appreciate the credit remaining in the source.  I must admit that after
  14. the original use, I haven't used it since, but you may find it
  15. useful...  one day.
  16.  
  17. Here are some of the thinking behind it.  I wanted a filter to do this,
  18. and I realised that I could use the 'ed' trick doing "g/^/m0" to
  19. reverse a file, but this would mean 'cat'ting to a temp file,
  20. reversing, and then 'cat'ting again.  This turned out very slow for
  21. large files (and 'ed' had an extra temp file of it's own).
  22.  
  23. I could use 'perl', using the script "print reverse ( <> )", but this
  24. would mean that the whole file is slurped into memory.  This could be a
  25. problem for very large files.
  26.  
  27. My perl solution is a halfway point.  It limits the amount of data held
  28. in core.  This can be set by changing "$maxbuf".  If the amount of data
  29. read exceeds this, it is dumped to a temp file, and the process
  30. continues.  For reversal of small files, it will be reasonably fast,
  31. since it is all done in core, and for larger files, the temp file stops
  32. the process becoming bloated.  I found it worked for me.
  33.  
  34. The limit "$maxbuf" is not absolute, since lines longer than "$maxbuf"
  35. are not split.  If the length of lines is small compared to it, then it
  36. will be fairly faithful to this value.  Something to watch out for, is
  37. that if the last line is missing the newline, in the output file, it
  38. gets glued to the next line.
  39.  
  40.     Over to you,
  41.         Alfie
  42. --
  43. Nick Holloway |  `O O'  | alfie@cs.warwick.ac.uk, alfie@warwick.UUCP,
  44. [aka `Alfie'] | // ^ \\ | ..!uunet!mcsun!ukc!warwick!alfie
  45.  
  46. #! /bin/sh
  47. # This is a shell archive, meaning:
  48. # 1. Remove everything above the #! /bin/sh line.
  49. # 2. Save the resulting text in a file.
  50. # 3. Execute the file with /bin/sh (not csh) to create the files:
  51. #    reverse.pl
  52. # This archive created: Wed Feb 13 17:58:54 1991
  53. export PATH; PATH=/bin:$PATH
  54. if test -f 'reverse.pl'
  55. then
  56.     echo shar: will not over-write existing file "'reverse.pl'"
  57. else
  58. cat << \SHAR_EOF > 'reverse.pl'
  59. #!/usr/local/bin/perl
  60.  
  61. # Program : reverse
  62. # Usage   : reverse [ file ... ]
  63. #             print out lines in files given (or stdin if none) in the 
  64. #             reverse order on the standard output
  65. # Author  : Nick Holloway <alfie@cs.warwick.ac.uk>
  66. # Date    : 11th January 1991
  67. # Place   : Computer Science Dept, University of Warwick, Coventry, UK
  68.  
  69. # $maxbuf - maximum number of bytes to keep in core
  70. # $tmpdir - directory to keep temp file in (overridden by env var TMPDIR)
  71. # @buffer - array used to keep current set of input lines
  72. # @tell   - array holding position and number of lines dumped to temp file
  73.  
  74. #-- configuration section
  75. $maxbuf = 8 * 1024;    # maximum number of bytes to keep in core
  76. $tmpdir = '/tmp';    # default temporary directory
  77.  
  78. #-- let battle commence...
  79. $0 =~ s%.*/%%;        # basename $0
  80.  
  81. #-- create temp file, open for update and unlink to avoid need to clean up.
  82. $tmp = ( $ENV { 'TMPDIR' } || $tmpdir ) . "/reverse.$$";
  83. open ( TMP, "+>$tmp" ) 
  84.     || die ( "$0: can't open \"$tmp\": $!\n" );
  85. unlink ( $tmp )
  86.     || die ( "$0: unlink of \"$tmp\" failed: $!\n" );
  87.  
  88. #-- read input, dumping reversed portions to temp file if necessary
  89. while ( <> ) {
  90.     $bufsiz += length;
  91.     if ( $bufsiz >= $maxbuf ) {
  92.     push ( @tell, tell ( TMP ), 0+@buffer );
  93.     print TMP reverse @buffer;    # reverse, and dump buffer to file
  94.     @buffer = ();            # empty buffer
  95.     $bufsiz = length;        # new buffer size
  96.     }
  97.     push ( @buffer, $_ );
  98. }
  99.  
  100. #-- print in-core buffer.
  101. print reverse @buffer;
  102.  
  103. #-- for each section dumped to file, print these out.
  104. while ( @tell ) {
  105.     $lns = pop ( @tell );
  106.     $pos = pop ( @tell );
  107.     seek ( TMP, $pos, 0 ) ||        # move to saved postion in file
  108.     die ( "$0: can't seek in temp file: $!\n" );
  109.     for ( 1 .. $lns ) {            # print lines dumped previously
  110.     print ''.<TMP>;
  111.     }
  112. }
  113. SHAR_EOF
  114. chmod +x 'reverse.pl'
  115. fi # end of overwriting check
  116. #    End of shell archive
  117. exit 0
  118.