====== 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]]