====== sed ======
Stream editor: applies edit commands to each line. GNU sed on Ubuntu.
===== The one command you'll use 95% of the time =====
sed 's/old/new/' # substitute, first match per line
sed 's/old/new/g' # all matches per line
sed 's/old/new/2' # only the 2nd match per line
sed -i 's/old/new/g' f # edit file in place
sed -i.bak 's/x/y/' f # in place, keeps f.bak
sed -E 's/(a)(b)/\2\1/' # extended regex + backrefs
Any delimiter works: useful for paths/URLs: ''sed 's|/a/b|/x/y|g'''.
''&'' in replacement = the whole match: ''sed 's/foo/[&]/g''' → ''[foo]''.
===== Addressing: //which// lines get the command =====
sed '5d' f # delete line 5
sed '5,10d' f # delete 5-10
sed '$d' f # last line
sed '2~3d' f # every 3rd line starting at 2
sed '/error/d' f # lines matching /error/
sed '/START/,/END/d' f # inclusive pattern range
sed '/START/,/END/!d' f # keep ONLY the range (! inverts)
sed -n '5,10p' f # print just lines 5-10 (-n + p)
sed -n '/error/p' f # print only matches (grep-like)
===== The commands beyond `s` =====
d delete line p print line (with -n)
a\ append after line i\ insert before line
c\ change whole line y/abc/ABC/ transliterate chars
sed '3i\inserted text' f # insert before line 3
sed '/pattern/a\appended' f # append after matches
sed 'y/abc/ABC/' f # like tr, per char
sed -n 's/x/y/p' f # print only changed lines
===== Multiple commands =====
sed -e 's/a/b/' -e '5d' f
sed 's/a/b/; s/c/d/' f # ; separates commands
sed '/skip/!s/a/b/' f # s on lines NOT matching
===== Useful regex bits (GNU sed BRE/ERE) =====
* Default is **BRE**: ''+'', ''?'', ''('', '')'', ''|'' need backslashes.
''sed 's/\(ab\)\+/X/'': or just always use ''sed -E'' (ERE) and forget it.
* ''\b'' word boundary, ''\w''/''\W'', ''\s''/''\S'' work in GNU sed.
* ''\( \)'' groups become ''\1''-''\9'' backrefs: ''sed -E 's/([0-9]+)x([0-9]+)/\2 by \1/'''.
* ''.*'' is greedy: ''sed -E 's/"(.*)"/\1/''' grabs the LAST quote pair.
Non-greedy needs ''[^"]*'': ''sed -E 's/"([^"]*)"/\1/'''.
===== Classic one-liners =====
sed 's/^[[:space:]]*//;s/[[:space:]]*$//' f # trim whitespace
sed 's/^/# /' f # comment out every line
sed -n 'x;$p' f || tail -1 f # last line (use tail)
sed -e :a -e 'N;$!ba' -e 's/\n/ /g' f # join all lines
sed 's/./&\n/g' f # one char per line
seq 5 | sed 's/^/item/' # generate
===== Gotchas =====
* ''-i'' without backup is irreversible: test without ''-i'' first.
* ''sed -i '''' is macOS syntax; GNU is ''sed -i'' (no arg). These pages assume
GNU sed on Linux.
* ''sed -z'' treats input as NUL-separated: for filenames from ''find -print0''.
* It processes line-by-line; multi-line matching needs ''N'', ''P'', ''D'': at that
point reach for ''perl -0777 -pe'' or awk.
===== See Also =====
* [[terminal:scripting:start|Scripting Index]]
* [[terminal:tools:start|CLI Tools]]
* [[terminal:start|Return to terminal]]
* [[start|Return to wiki home]]