shell pipeline to reverse the order of lines.

David C Lawrence tale at rpi.edu
Sat Feb 16 19:35:03 AEST 1991


In <9102151917.AA04419 at wendy-fate.UU.NET> kyle at UUNET.UU.NET (Kyle Jones):

   After seeing a couple of programs in Perl and Icon to do this, I
   feel compelled to post a shell pipeline solution to this problem.

And I an Emacs-Lisp one, though Kyle could have handled it himself.  I
actually wrote this several months ago.  It was the speediest of a few
very simple algorithms, but also very costly in memory usage.  It is
longer than it would be were it to just do the original task of
reversing a file, but working with a region adds a little more to its
length (and to me, its value).

(defun reverse-region (beg end)
  "Reverse the order of lines in a region.
>From a program takes two point or marker arguments, BEG and END."
  (interactive "r")
  (if (> beg end)
      (let (mid) (setq mid end end beg beg mid)))
  (save-excursion
    ;; put beg at the start of a line and end and the end of one --
    ;; the largest possible region which fits this criteria
    (goto-char beg)
    (or (bolp) (forward-line 1))
    (setq beg (point))
    (goto-char end)
    ;; the test for bolp is for those times when end is on an empty line;
    ;; it is probably not the case that the line should be included in the
    ;; reversal; it isn't difficult to add it afterward.
    (or (and (eolp) (not (bolp))) (progn (forward-line -1) (end-of-line)))
    (setq end (point-marker))
    ;; the real work.  this thing cranks through memory on very large regions.
    (let (ll (do t))
      (while do
	(goto-char beg)
	(setq ll (cons (buffer-substring (point) (progn (end-of-line) (point)))
		       ll))
	(setq do (/= (point) end))
	(delete-region beg (if do (1+ (point)) (point))))
      (while (cdr ll)
	(insert (car ll) "\n")
	(setq ll (cdr ll)))
      (insert (car ll)))))

--
   (setq mail '("tale at cs.rpi.edu" "tale at ai.mit.edu" "tale at rpitsmts.bitnet"))



More information about the Alt.sources.d mailing list