| name | sed-awk |
| description | Text processing with sed and awk — find-and-replace, column extraction, reformatting, and stream editing. Use when user mentions "sed", "awk", "text processing", "find and replace in files", "column extraction", "stream editing", "text transformation", "reformat output", or processing text from command-line output. |
sed and awk
sed basics
Substitute
sed 's/old/new/' file.txt
sed 's/old/new/g' file.txt
sed 's/old/new/gI' file.txt
Delete lines
sed '5d' file.txt
sed '5,10d' file.txt
sed '/^$/d' file.txt
sed '/DEBUG/d' file.txt
Insert, append, and in-place editing
sed '3i\new line here' file.txt
sed '3a\new line here' file.txt
sed -i 's/old/new/g' file.txt
sed -i '' 's/old/new/g' file.txt
sed -i.bak 's/old/new/g' file.txt
sed addresses
sed '3s/old/new/' file.txt
sed '3,7s/old/new/' file.txt
sed '/START/,$s/old/new/' file.txt
sed '/BEGIN/,/END/s/old/new/' file.txt
sed '1~2s/old/new/' file.txt
sed '/KEEP/!d' file.txt
sed with regex
sed 's/\(foo\)\(bar\)/\2\1/' file.txt
sed -E 's/(foo)(bar)/\2\1/' file.txt
sed -E 's/([0-9]{4})-([0-9]{2})-([0-9]{2})/\2\/\3\/\1/' file.txt
sed -E 's/<[^>]+>//g' file.html
sed -E 's/^[[:space:]]+//; s/[[:space:]]+$//' file.txt
Multiple commands
sed -e 's/foo/bar/' -e 's/baz/qux/' file.txt
sed 's/foo/bar/; s/baz/qux/' file.txt
awk basics
Print columns
awk '{print $2}' file.txt
awk '{print $1, $3}' file.txt
awk '{print $NF}' file.txt
Field separator
awk -F',' '{print $2}' data.csv
awk -F':' '{print $1, $3}' /etc/passwd
awk -F'[,;]' '{print $1, $2}' file.txt
awk -F',' -v OFS='\t' '{print $1, $3}' data.csv
Built-in variables
awk '{print NR, NF, $0}' file.txt
awk 'BEGIN{FS=","; OFS="\t"} {print $1, $2}' data.csv
awk '{print FILENAME, NR, $0}' *.txt
awk patterns and actions
BEGIN and END blocks
awk 'BEGIN{print "Name\tScore"} {print $1, $2} END{print "---done---"}' file.txt
awk 'END{print NR, "lines"}' file.txt
Conditionals
awk '$3 > 100' file.txt
awk '/ERROR/' file.txt
awk '!/DEBUG/' file.txt
awk '$1 == "admin" {print $2}' file.txt
awk '$2 ~ /^192\.168/' file.txt
awk '{if ($3 > 90) print $1, "pass"; else print $1, "fail"}' file.txt
Arithmetic
awk '{sum += $2} END{print sum}' file.txt
awk '{sum += $2; n++} END{print sum/n}' file.txt
awk 'NR==1 || $3 > max {max=$3} END{print max}' file.txt
awk string functions
awk '{split($0, parts, ":"); print parts[1]}' file.txt
awk '{print substr($1, 1, 3)}' file.txt
awk '{gsub(/foo/, "bar"); print}' file.txt
awk '{if (match($0, /[0-9]+/)) print substr($0, RSTART, RLENGTH)}' file.txt
awk '{printf "%-20s %10.2f\n", $1, $2}' file.txt
awk 'length($0) > 80' file.txt
awk '{print tolower($1)}' file.txt
Common recipes
Extract column from CSV
awk -F',' '{print $3}' data.csv
awk -F'","' '{gsub(/^"|"$/, "", $2); print $2}' data.csv
Reformat log lines
awk '{print $1, $7}' access.log
sed -E 's/^([A-Z][a-z]+ [0-9]+ [0-9:]+) [^ ]+ (.+)/\1 | \2/' /var/log/syslog
Bulk rename patterns across files
find . -name '*.py' -exec sed -i '' 's/old_func/new_func/g' {} +
grep -rl 'old_func' --include='*.py' . | xargs sed 's/old_func/new_func/g' | head -20
Swap fields
awk '{temp=$1; $1=$2; $2=temp; print}' file.txt
sed -E 's/^([^ ]+) ([^ ]+)/\2 \1/' file.txt
Remove duplicate lines
awk '!seen[$0]++' file.txt
awk '!seen[$2]++' file.txt
Sum a column
awk '{s+=$2} END{print s}' file.txt
awk -F',' '/SALE/ {s+=$4} END{printf "%.2f\n", s}' data.csv
More one-liners
sed -n '/START/,/END/{/START/d;/END/d;p}' file.txt
paste -sd',' file.txt
sed 's/^/PREFIX: /' file.txt
sed 's/\r$//' file.txt
sed -n 's/.*"\([^"]*\)".*/\1/p' file.txt
awk '{print $1}' file.txt | sort | uniq -c | sort -rn
sed vs awk: when to use which
| Task | Use |
|---|
| Find-and-replace | sed |
| Delete/filter lines by pattern | sed (or grep) |
| In-place file editing | sed |
| Column extraction | awk |
| Arithmetic, aggregation | awk |
| Conditional logic per line | awk |
| Reformatting structured text | awk |
Rule of thumb: if you need columns or math, use awk. If you need search-and-replace or line deletion, use sed.
Gotchas
BSD vs GNU sed
| Feature | GNU sed (Linux) | BSD sed (macOS) |
|---|
| In-place edit | sed -i 's/.../.../' | sed -i '' 's/.../.../' |
\t in replacement | Supported | Not supported (use literal tab) |
| Case-insensitive flag | s/old/new/I | Not available |
Line stepping 1~2 | Supported | Not available |
\+, \? in basic regex | Supported | Not supported (use -E) |
Portable approach: always use -E for extended regex and -i.bak for in-place editing on both platforms.
Quoting in shell
sed 's/$HOME/replaced/' file.txt
sed "s/$HOME/replaced/" file.txt
name="world"
sed "s/hello/$name/" file.txt
sed 's|/usr/local/bin|/opt/bin|g' file.txt
sed 's#old/path#new/path#g' file.txt
name="admin"
awk -v user="$name" '$1 == user {print $2}' file.txt
awk '$1 == "$name"' file.txt