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.
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
3 is the input address,
m is the move command and
0 is the target address. To do the same with
$ printf '3m0\nwq\n' | ed -s ip.txt - $ cat ip.txt cherry apple banana fig mango pineapple
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.
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
$ cat colors.txt red green blue yellow black $ printf '$-2d\nwq\n' | ed -s colors.txt - $ cat colors.txt red green yellow black