Path: utzoo!utgpu!cs.utexas.edu!sdd.hp.com!wuarchive!uwm.edu!rpi!tale From: tale@rpi.edu (David C Lawrence) Newsgroups: alt.sources.d Subject: Re: shell pipeline to reverse the order of lines. Message-ID: <3*-&S|^@rpi.edu> Date: 16 Feb 91 08:35:03 GMT References: <1991Feb15.164342.4552@midway.uchicago.edu> <9102151917.AA04419@wendy-fate.UU.NET> Organization: Rensselaer Polytechnic Institute Computer Science, Troy NY Lines: 45 Nntp-Posting-Host: cs.rpi.edu In <9102151917.AA04419@wendy-fate.UU.NET> kyle@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@cs.rpi.edu" "tale@ai.mit.edu" "tale@rpitsmts.bitnet"))