'Sed' stands for stream editor. Think of it as a program that edits a text file on a per line basis.
1. The 's' stands for 'substitute'
You'll probably see the following pattern very frequently.
It basically means you're matching
pattern1 and substituting for
& operator is the full match
Everything that was matched in
pattern1 can be referenced in
pattern2 with the
& character. No need to enclose the whole regex in parenthesis.
Append "bacon" to every line, because everything gets better with bacon.
3. The matching is greedy and there's no + modifier
When a simple matching pattern like
[a-z]*, that matches a sequence of zero or more characters from a to z is used, it may not behave exactly the way you'd expect. In "abc 123" it would match "abc", but in "123 abc" it would match "", an empty string. Because the matching is greedy and it's going to try to find the biggest match as soon as possible.
In the GNU version of sed, it is possible to use the
-r option to enable the extended regular expressions and change it to
[a-z]+, that matches a sequence of one or more characters from a to z.
Sadly, there's no regex
+ operator in the original sed implementation, and that's the built in version in Mac OS X, BOOO.
A workaround this issue in the original implementation, would be to force the matching of at least one character by changing the regex to
4. Escape ALL the parenthesis
Parenthesis create matching groups. When creating a group in your matching pattern, the parenthesis must be escaped.
I don't fully understand why, but it won't work otherwise.
5. Any character may be used as a delimiter
It can be useful when matching system paths. By changing the delimiter, from say
:, there's no need to escape all the backslashes, so
6. More than one expression can be on the same command
Have you ever wondered what that
-e option is? It stands for expression, and besides being optional when you have only one pattern, it can be useful when you have multiple. Let's see an example:
Imagine a script that capitalizes all vogals. To do that you could pipe sed commands together like:
And it will work just fine. By the way, the
g flag modifier at the end stands for global, and means that all matches are going to be processed, only the first occurence in each line is matched by default.
Okay, but that code will trigger five processes, one per command, what you can do to achieve the same results while using only one sed process is to use the
-e option, and the code will give the exact same results, the command would be:
7. The lonely comma is the content between two patterns
You can print the content between to line matches with sed using:
-n means "silent mode", and prevents sed from outputting to stdout, but the
p flag at the end instructs sed to print the lines that matched the command, result: the output is only the contents delimited by the patterns (including the pattern delimiters).