Sed - An Introduction and Tutorial by Bruce Barnett
Hardly worth the buildup. All that prose and the solution is just matching squiggles. Well,there is one complication. Since each?sed?command must start on its own line,the curly braces and the nested?sed?commands must be on separate lines. Previously,I showed you how to remove comments starting with a "#." If you wanted to restrict the removal to lines between special "begin" and "end" key words,you could use:? #!/bin/sh # This is a Bourne shell script that removes #-type comments # between 'begin' and 'end' words. sed -n ' /begin/,/end/ { s/#.*// s/[ ^I]*$// /^$/ d p } ' Click here to get file:?These braces can be nested,which allow you to combine address ranges. You could perform the same action as before,but limit the change to the first 100 lines:? #!/bin/sh # This is a Bourne shell script that removes #-type comments # between 'begin' and 'end' words. sed -n ' 1,100 { /begin/,/end/ { s/#.*// s/[ ^I]*$// /^$/ d p } } ' Click here to get file:?You can place a "!" before a set of curly braces. This inverts the address,which removes comments from all lines?except?those between the two reserved words:? #!/bin/sh sed ' /begin/,/end/ !{ s/#.*// s/[ ^I]*$// /^$/ d p } ' Click here to get file:? You may remember that I mentioned you can do a substitute on a pattern range,like changing "old" to "new" between a begin/end pattern: #!/bin/sh sed ' /begin/,/end/ s/old/new/ ' Another way to write this is to use the curly braces for grouping: #!/bin/sh sed ' /begin/,/end/ { s/old/new/ } ' I think this makes the code clearer to understand,and easier to modify,as you will see below. If you did not want to make any changes where the word "begin" occurred,you could simple add a new condition to skip over that line: #!/bin/sh sed ' /begin/,/end/ { /begin/n # skip over the line that has "begin" on it s/old/new/ } ' However,skipping over the line that has "end" is trickier. If you use the same method you used for "begin" then the sed engine will not see the "end" to stop the range - it skips over that as well. The solution is to do a substitute on all lines that don't have the "end" by using #!/bin/sh sed ' /begin/,/end/ { /begin/n # skip over the line that has "begin" on it /end/ !{ s/old/new/ } } ' You may remember that the substitute command can write to a file. Here again is the example that will only write lines that start with an even number (and followed by a space):? sed -n 's/^[0-9]*[02468] /&/w even' |