ed (and a little ex) ==================== Ed is a line-oriented editor. See ed(1). Although ed is significantly more primitive than screen-oriented editors like vi, it's still useful for automation and in constrained environments (such as OpenBSD's single-user mode). Ed has two modes: command and input. It starts in command mode. In command mode, ed reads commands from standard input, and executes the commands to manipulate the contents of the edit buffer. Commands such as "a" (append), "i" (insert), or "c" (change) cause ed to enter input mode. In input mode, ed writes standard input to the edit buffer. Exit input mode with a single period (".") on a new line. All commands operate on an entire line (or multiple lines). See ed(1) for a complete list of commands. H Turn on error explanations q Quit Q Quit, discarding any unsaved changes u Undo last command w Write file (Shell magic doesn't work so use "w /home/me/foo.txt" instead of "w ~/foo.txt".) p print line(s) (Print all lines like ",p".) i Insert before line a Append after line d Delete line m Move line t copy line to after line (3t8) P Show a Prompt character ("*" by default, or as set on command line with -p flag) Commands can be prefixed with line numbers, like in sed. Also like in sed, ed addresses are 1-based, so "1p" prints the first line of a file, and "0p" returns "Invalid address". % ed i In visions of the dark night But a waking dram of life and light . 1p In visions of the dark night n 1 In visions of the dark night ,n 1 In visions of the dark night 2 But a waking dram of life and light p But a waking dram of life and light n 2 But a waking dram of life and light 1 In visions of the dark night n 1 In visions of the dark night 2 But a waking dram of life and light n 2 But a waking dram of life and light 1 In visions of the dark night a I have dreamed of joy departed--- foo . ,n 1 In visions of the dark night 2 I have dreamed of joy departed--- 3 foo 4 But a waking dram of life and light 3d 2,3n 2 I have dreamed of joy departed--- 3 But a waking dram of life and light 3a Hath left me broken-hearted . 2,$n 1 In visions of the dark night 2 I have dreamed of joy departed--- 3 But a waking dram of life and light 4 Hath left me broken-hearted 3s/dram/dream/ 3p But a waking dream of life and light w poe.txt 127 q % Moving line: ,n 1 Second line entered 2 The first line entered. 1m2 ,n 1 The first line entered. 2 Second line entered Regular expressions: g/foo/p Select lines matching "foo" and print them. v/bar/p Select lines NOT matching "bar" and print them. g/bas/m$ Move lines matching "bas" to end of file. /foo Search ahead for lines containing "foo". ?foo Search backward for lines containing "foo". s/foo/bar Substitute first occurrence of "foo" with "bar". s/foo/bar/g Substitute all occurrences of "foo" with "bar". Read output of external command into buffer: r !cal -m ## ed one-liners ## % echo '/Search string\ni\nEd inserted line\n.\nw' | ed file.txt % ed -s check_sender_access <<< $'H\n3d\nw' ## ed scripts ## N.B. — it's safer to use the stream editor `sed` where it's possible to stream-ify the editing task. Imagine we have a `foo.ed` text file full of ed commands: /clusterfuck/s/clusterfuck/incident/ $ a The end. . wq We can run these commands against a text file: % ed file.txt < foo.ed If ed encounters any error — including not finding a search term — it stops execution of the script. In the case of a search, we can have it not stop by prepending the `g` flag like `g/clusterfuck/s/clusterfuck/incident/`. Of course, adding the 'g' flag causes it to replace all instances rather than just the first. Again, `sed` is the safer choice, where possible. ## red ## If we invoke `ed` in a Bash script, for example, it may be better to call it as `red`. `red` is _restricted_ ed — it only edits files in the current directory and does not execute shell commands. ## ex ## ex was originally an extension of ed. Nowadays, it's a shortcut to start vi(m) ex mode. We can use it for one-liners. The `-c` flag executes its argument as an ex command, and can be specified up to ten times. Pipe (|) is a command separator, but it doens't seem to let us put multiple commands in one `-c` argument. Insert a line before % ex -c'/search string' -c'i|My Inserted line' -c'wq' file.txt We could also source a file full of ex commands: % ex -c 'source foo.ex' file.txt ## Links ## - http://man.openbsd.org/OpenBSD-current/man1/ed.1 - http://wiki.bash-hackers.org/howto/edit-ed - https://www.gnu.org/software/ed/manual/ed_manual.html - https://utcc.utoronto.ca/~cks/space/blog/sysadmin/EdScriptErrorProblem - https://www.gnu.org/software/diffutils/manual/html_node/ed-Scripts.html