- This is not absolutely perfect and up to the highest standards of Posix and sed usage. It was kindly pointed to me by people from HN. I'll try and make this the best possible version I can and I'll listen to your feedback. I'm not a sed guru after all, just someone trying to follow the 20/80 formula (even though sometimes I go waaay overboard).
- There is no mention of the hold space (and other registers) usage. Personally I found their usage quite confusing. If this might change in the future I'll adjust this. After all, this is not "The ultimate sed reference" but "useful sed".
- There might be examples where I use -E (regexp extended option) when it is not necesarilly needed. Chances are you'll want to use this in most of your operations so it might not be a bad reflex to have. Sure, you could make an alias for it in your .bashrc. Personally I try and delay usage of aliases until I feel it's absolutely necesarry (as it hides some verbosity which makes the commands clearer).
sed -n '10p' myfile.txt
sed '5!/s/foo/bar/' file.txt
sed '/^hello/ s/h/H/' file.txt
sed '5,$ s/foo/bar/' file.txt
sed -nr '/^foo/,/^bar/p' file.txt
sed 's_/bin/bash_/bin/sh_' file.txt
Custom delimiters for regex adress combined with the classical delimiter for substitute command (you could also use there a custom delimiter). Useful for paths.
sed '\_/bin/bash_s/grep/egrep/' file.txt
- or using the same delimiter for clarity
sed '\_/bin/bash_s_grep_egrep_' file.txt
sed 's/[a-zA-Z]/& /g' file.txt
keep the first word of every line (where word is defined by alnum chars + underscores for simplicity sake)
sed -E s_[a-zA-Z0-9_]+.*_\1_' file.txt
sed -E 's_([a-zA-Z0-9_]*) ([a-zA-Z0-9_]*)_\2 \1_' f1
sed -E 's_([a-zA-Z0-9_]+) \1_\1_ig' f1
sed 's_foo_bar_w replaced.txt' file.txt
sed -e 's_foo_bar_' -e 's_hello_HELLO_' file.txt
#!/bin/bash
sed '
s/a/A/
s/foo/BAR/
s/hello/HELLO/
' <$1
- call with
./myscript.sh myfile.txt
sed -E '/start/,/end/ s/#.*//' file.txt
sed '/start/,$ d' file.txt
sed -rn '/start/,/end/ !p' file.txt
sed '/start/q' file.txt
sed '5 r newfile.txt' file.txt
sed '/foo/a\ AFTER FOO' file.txt
sed '/foo/i\ BEFORE FOO' file.txt
sed '/foo/c\ FOO IS CHANGED' file.txt
Nested sed ranges with inversion. Between lines 1,100 apply actions where the pattern DOESN'T match.
#!/bin/bash
sed '
1,100 {
/foo/ !{
s_hello_HELLO_
s_yes_YES
}
}'
- call with
./script.sh <file.txt
Use nested addresses with change, insert and append to modify: the line before match, the line with match, the line after match.
#!/bin/bash
sed '
/^#/ {
i\
#BEFFORE ORIGINAL COMMENt
a\
#AFTER ORIGINAL COMMENT
c\
# ORIGINAL COMMENT IS NOW THIS LINE
}'
Insert new line before the first comment, after the first comment put in the contents of file and quit immediately afterwards
#!/bin/bash
sed '
/^#/ {
i #BEFORE COMMENT
r myotherfile.txt
q
}'
sed 'y/abc/ABC/' file.txt
sed -E '/^#/w comments.txt' file.txt
sed '1~2p' file.txt
sed -i.bak 's/hello/HELLO/' file.txt