ed(1) is the right tool (VII) =================================== The nice thing about TODO-lists is that you will eventually be able to get through them and pencil-out all the completed tasks. But sometimes it is good to keep track of the many things you have accomplished by going through a TODO-list. So I normally just save the finised tasks in a "WELL-DONE" file, to give myself a reassuring (although fictitious) pat in the shoulder. Let's have a look at our current TODO-list: $ ed TODO.txt 176 1,$p TODO LIST - buy some tomatoes - buy some tea + configure Unix V7 outpost + read Schismatrix * phlog about ed(1) * put rubbish bins outside * make a tea * check postgrey hiccup As per our choice, all the lines starting with "*" denote completed tasks. If we want to copy all of them to a file named "WELL-DONE", ed(1) knows a useful trick or two: 6,9w WELL-DONE 84 We should be able to figure out what might have happened here using our current ed-fu. "6,9" specifies a set of lines (all the lines between 6 and 9, both included), while "w" is the command to "write" ed(1) buffers to a file. We have also seen than "w" followed by a file name will actually dump all the current content of ed(1)'s buffer on that file. Well, this is exactly what happened here, only we told ed(1) to dump a range of lines (6-to-9) instead of the whole buffer, and the destination file is called WELL-DONE. We can check if our intuition is correct by exiting ed(1) and using cat(1) on the file WELL-DONE. The good news is that we don't need to exit ed(1) at all: !cat WELL-DONE * phlog about ed(1) * put rubbish bins outside * make a tea * check postgrey hiccup ! Wait, what was that? Let's give it another shot: !pwd /home/katolaz/tmp ! this can't be what we think it is, right? !ls -l total 8 -rw-r--r-- 1 katolaz katolaz 176 Oct 10 10:39 TODO.txt -rw-r--r-- 1 katolaz katolaz 84 Oct 11 05:35 WELL-DONE ! OK, OK, we got it! ed(1) uses the command "!" to "shell out" another command, i.e., to execute a command of our choice as if we were typing it at the shell's prompt. The "!" command will execute the command you type, show its output on the screed (beware, ONLY on the screen, without affecting your current buffer), and then finish with a single "!" on a line. At that point, we know that the external command has finished, and ed(1) is ready to receive more commands: 1,$p TODO LIST - buy some tomatoes - buy some tea + configure Unix V7 outpost + read Schismatrix * phlog about ed(1) * put rubbish bins outside * make a tea * check postgrey hiccup Quite handy, right? Notice again that the invocation of external commands through "!" does *not* modify the current buffer. So we have successfully written lines 6-9 to the file called "WELL-DONE" in the current directory. Now we remove them from TODO.txt: g/^\* /d 1,$p TODO LIST - buy some tomatoes - buy some tea + configure Unix V7 outpost + read Schismatrix to keep our TODO-list in order. I also did my shopping yesterday, so: g/buy/s/^-/\*/ 1,$p TODO LIST * buy some tomatoes * buy some tea + configure Unix V7 outpost + read Schismatrix but now I would like to append the newly-completed tasks to the file "WELL-DONE". If we used (don't do it!): 2,3w WELL-DONE ed(1) would silently destroy the previous content of WELL-DONE, and put there the two tasks we just completed. But this is not what we want: remember, keeping track of the stuff you have done is a good boost for yout morale! The ed(1) command to "append" lines at the end of an existing file is instead "W": 2,3W WELL-DONE 35 !cat WELL-DONE * phlog about ed(1) * put rubbish bins outside * make a tea * check postgrey hiccup * buy some tomatoes * buy some tea ! We can now remove the completed tasks and save our current TODO.txt file: 2,3d w 57 1,$p TODO LIST + configure Unix V7 outpost + read Schismatrix What if we want to re-insert our old (completed) tasks somewhere in our TODO.txt file, e.g., after line 1? Simple: 1r WELL-DONE 119 1,$p TODO LIST * phlog about ed(1) * put rubbish bins outside * make a tea * check postgrey hiccup * buy some tomatoes * buy some tea + configure Unix V7 outpost + read Schismatrix And our old (completed) tasks are back. But no, we really don't need to see them here: u 1,$p TODO LIST + configure Unix V7 outpost + read Schismatrix w 57 q Note that in the versions of ed(1) currently available in most unix operating systems (including Linux, OpenBSD, FreeBSD, NetBSD), the "r" command can also read lines from an external command into an ed(1) buffer. For instance $ ed filelist filelist: No such file or directory r ! ls -l 125 1,$p total 8 -rw-r--r-- 1 katolaz katolaz 57 Oct 11 06:01 TODO.txt -rw-r--r-- 1 katolaz katolaz 119 Oct 11 06:00 WELL-DONE which is sometimes very handy. This option was not available to the original versions of ed(1) up to UNIXv7. In that case, you would use a simple trick: $ ed filelist filelist: No such file or directory ! ls -l > tmp ! r tmp 178 1,$p total 8 -rw-r--r-- 1 katolaz katolaz 57 Oct 11 06:01 TODO.txt -rw-r--r-- 1 katolaz katolaz 119 Oct 11 06:00 WELL-DONE -rw-r--r-- 1 katolaz katolaz 0 Oct 11 06:06 tmp which (almost) does the job. -+-+-+-