`sed`: A Guide for Mere Mortals: 02
Software : GNU SED Version : 4.2.1 Compatibility : Any Copy of SED
Welcome back Cyber Wizards. This week on “`sed`: A guide for Mere mortals” We’re going to go over some more basic, but useful, sed sorcery. This time we are focusing on refining what we are changing, and understanding some more basic principles that will help build a solid foundation.
Recap, and examples
First lets examine example.txt, and note that we are working with all numbers today:
1 22 22 2 22 23 3 42 32 4 34 23
From The First installment of this guide we can derive a basic syntax for working with these numbers.
IE if you wanted to change the number 22 to 17, you might do:
sed 's/22/17/' example.txt
(you might also use the -i option to edit the file in place, but for this example we’ll leave the original file intact)
1 17 22 2 17 23 3 42 32 4 34 23
As you can see, this changes the first occurrence of each number: 22 to 17.
You could also use:
sed 's/22/17/g' example.txt
1 17 17 2 17 23 3 42 32 4 34 23
which as you can see changes all occurrences of 22 to 17
Which is fine and dandy if you live in a vacuum sealed sterile environment that hands you situations that are that simple… If that were the case you wouldn’t be learning about sed though, because life would be easy and pencils would taste like bacon.
Let’s go a step further, lets say this is some sort of numerical config file, and you don’t even know that the number you care about is 22. As learned in our regex guide you could do something along the lines of:
sed 's/[0-9][0-9]*/17/g' example.txt
which would match any number of at least one number, and replace it with 17, and give you:
17 17 17 17 17 17 17 17 17 17 17 17
which is clearly MORE useful.
How to solve this? row numbers and pattern numbers. You can place a number before your substitute statement to determine which line you care about. AND rather then using “g” for “global” you can use a number to determine which occurrence of the pattern you care about.
IE If you wanted to replace the second row, third column, you could do:
sed '2s/[0-9][0-9]*/17/3' example.txt
1 22 22 2 22 17 3 42 32 4 34 23
For the row determination, you can also do a range rows by separating with commas:
sed '2,4s/[0-9][0-9]*/17/3' example.txt
1 22 22 2 22 17 3 42 17 4 34 17
And lastly, you can target the last row, using $ instead of a line number:
sed '$s/[0-9][0-9]*/17/2' example.txt
1 22 22 2 22 23 3 42 32 4 17 23
While this was a fairly single minded set of examples, it does build a nice foundation to start learning the more complex nuances of sed. In my travels through the kingdom of sed, I have learned that it’s these simple little parts of the command that are generally the hardest to internalize and bring out at a moments notice. The more complicated aspects are generally easier to imagine, so by taking the time to learn simple way’s of refining your patterns, you can gain a great deal of control later in your struggles.
All in all, I hope you have found this read useful, please stay tuned for the next installment, where I believe we will be focusing on keeping bits of pattern and moving it around within your sed command.