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