CLI text editing with ed
I'm finally writing a post on the ed
command. And I'm keeping it short so that I'll actually publish the post. The examples presented below will be easier to understand for those already familiar with Vim and sed
. See the links at the end for learning resources.
Although I'm interested in getting to know ed
better, I don't really find myself in situations where it'd help me. But, I have used it a few times to answer questions on stackoverflow.
Moving lines
Consider this sample input file:
$ cat ip.txt
apple
banana
cherry
fig
mango
pineapple
Suppose, you want to move the third line to the top. If you are using Vim, you can execute :3m0
where 3
is the input address, m
is the move command and 0
is the target address. To do the same with ed
:
$ printf '3m0\nwq\n' | ed -s ip.txt -
$ cat ip.txt
cherry
apple
banana
fig
mango
pineapple
The 3m0
part in the above ed
command is identical to the Vim solution. After that, another command wq
(write and quit) is issued to save the changes (again, Vim users would be familiar with this combination). The -s
option suppresses diagnostics and other details. -
is used to indicate that the ed
script is passed via stdin.
You can also move lines based on a regexp match. Here's an example:
# move the first matching line containing 'an' to the top of the file
$ printf '/an/m0\nwq\n' | ed -s ip.txt -
$ cat ip.txt
banana
cherry
apple
fig
mango
pineapple
If you want to move all the matching lines, you can use the g
command (same as Vim). Note that the first matching line will be moved first, then the next matching line and so on. So the order will be reversed after the move.
$ printf 'g/app/m0\nwq\n' | ed -s ip.txt -
$ cat ip.txt
pineapple
apple
banana
cherry
fig
mango
Here's the stackoverflow link that inspired the above examples. See this stackoverflow answer for more examples of moving lines. See this one to learn how to copy a particular line to the end of the file. See this unix.stackexchange answer for an example of moving a range of lines, where the same regex matches both the starting and ending lines.
Negative addressing
There are plenty of addressing features provided by the GNU sed
command, but negative addressing isn't one. Here's an example of deleting the last but second line using ed
:
$ cat colors.txt
red
green
blue
yellow
black
$ printf '$-2d\nwq\n' | ed -s colors.txt -
$ cat colors.txt
red
green
yellow
black