Sed
From World’s best introduction to sed
sed workflow
4 spaces of sed
- Input Stream
- Pattern Space
- Hold Buffer
- Output Stream
Basic work flow of sed
- Read from input stream input until ‘\n’, put content into pattern space (not ‘\n’ is not put into)
- Operate on pattern space. Hold buffer is temporary buffer for we to use.
- Output to the output stream, add a ‘\n’
Useful options
-n
option tells sed not to output the pattern space by default. Usep
command to force output.-i
is dangerous, safer to use the file extension to create a copy before modifying the content, e.g.-i.bak
.-e
to combine multiple command. Or use;
to separate command.The following 2 are the same:
sed -n 's/foo/bar/; p' sed -n -e 's/foo/bar/' -e 'p'
-r
use extended regular expression, make characters like+
magic character
Specifying command range
Line number (similar with Vim’s command range command)
Replace on line 5 to 10:
sed '5,10s/pat/foo/'
Print only line 5 to 10:
sed -n '5,10p'
Invert range, replace except line 5 to line 10:
sed '5,10!s/pat/foo/'
$
means the last line
Use regular expression (similar with awk)
This emulates grep:
sed -rn '/\d*/p'
Can use regex to specify range. Example, delete lines from the first line which matches
/foo/
to the first line matches/bar/
, inclusivesed '/foo/,/bar/d'
Hold buffer
Suppose you have a problem where you want to print the line before the line that matches a regular expression. How do you do this? Hold buffer can solve this problem.
h
copy pattern space to hold bufferg
copy hold buffer to pattern spacex
exchange pattern space and hold buffer
Solving the problem:
sed -n '/regex/{x;p;x}; h'
Note command grouping here: {x;p;x}
is a command group, and only get executed
when the pattern matches the regex, while the h
is executed for each line.
This does not work if the first line matches the regex, fix it:
sed -n '/regex/{x;1!p;x}; h'