awk + sed Cheatsheet — 80+ One-Liners for Text Processing on Linux and macOS
awk + sed cheat sheet — 80+ one-liners for text processing, with real examples and common pitfalls.
Runs locally
CategoryDeveloper & DevOps
Best forFormatting, validating, shrinking, or inspecting code-adjacent text.
Tool:
Section:
168 commands
sed · Basics (26)
sed 's/old/new/' file
Replace the FIRST occurrence of `old` on each line with `new`. Default sed substitution: per-line, first match only.
Input
old old old
foo old bar old
Output
new old old
foo new bar old
Examples
sed 's/cat/dog/' pets.txt
echo 'hello world' | sed 's/world/sed/'
sed 's/old/new/g' file
Global replace — substitute EVERY occurrence on each line, not just the first.
Input
old old old
Output
new new new
⚠ Common pitfall: Forgetting g is the #1 sed surprise. `sed s/,/|/` on a CSV row swaps only the first comma.
Examples
sed 's/ /_/g' file.txt
sed -i 's/http:/https:/g' index.html
sed 's/old/new/2' file
Replace only the Nth match on each line (here the 2nd). Numeric flag.
Input
a a a a
Output
a new a a
Examples
sed 's/,/|/3' csv-row.txt # change only the 3rd comma
sed 's/old/new/3g' file
Combine N and g: replace from the Nth match to the end of the line.
Input
x x x x x
Output
x x new new new
Examples
sed 's/ /_/2g' file # keep first space, underscore the rest
sed -n '5p' file
Print only line 5. `-n` mutes the default print, `p` prints the address.
Input
a
b
c
d
e
f
Output
e
Examples
sed -n '5p' /etc/passwd
sed -n '100,200p' big.log # range
sed -n '10,20p' file
Print line range 10–20 inclusive. Faster than head + tail.
Input
(file with 30 lines)
Output
(lines 10 through 20)
Examples
sed -n '10,20p' big.log
sed -n '/START/,/END/p' file # regex range
sed '5d' file
Delete line 5 and print the rest.
Input
a
b
c
d
e
Output
a
b
c
d
Examples
sed '1d' file.csv # strip header row
sed '$d' file # drop last line
sed '/^$/d' file
Delete empty lines (zero characters between start ^ and end $).
Input
a
b
c
Output
a
b
c
⚠ Common pitfall: This only catches truly empty lines. For lines with spaces/tabs use `/^[[:space:]]*$/d`.
Examples
sed '/^$/d' notes.md
sed '/^[[:space:]]*$/d' file # also blanks
sed '/pattern/d' file
Delete every line that matches a regex.
Input
ok 1
err 2
ok 3
err 4
Output
ok 1
ok 3
Examples
sed '/^#/d' config # drop comment lines
sed '/DEBUG/d' app.log
sed '5i\
NEW LINE' file
Insert a new line BEFORE line 5. The text after i\\ becomes the inserted line.
Input
a
b
c
d
e
f
Output
a
b
c
d
NEW LINE
e
f
Examples
sed '1i\
#!/bin/bash' script.sh # add shebang at top
sed '5a\
appended text' file
Append a new line AFTER line 5.
Input
1
2
3
4
5
6
Output
1
2
3
4
5
appended text
6
Examples
sed '$a\
EOF marker' file # append at end
sed '5c\
replacement' file
Change (replace entirely) the matching line(s) with new text.
Input
a
b
old line
d
Output
a
b
replacement
d
Examples
sed '/^TODO/c\
DONE' tasks.md
sed 'y/abc/xyz/' file
Transliterate characters: every `a`→`x`, `b`→`y`, `c`→`z`. Like `tr` but inside sed.
Input
cab cab
Output
zxy zxy
Examples
sed 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' file # upper-case
sed -E 's/[0-9]+/N/g' file
Extended regex with -E: replace any run of digits with N. -E enables ERE (no backslash before +, ?, |).
Input
order 42 then 1337
Output
order N then N
⚠ Common pitfall: GNU sed accepts -r as an alias for -E; BSD only takes -E. Always write -E for portability.
Examples
sed -E 's/(\w+)@(\w+)/REDACTED/g' file
sed -n '1,5p' file
Print the first 5 lines — a sed equivalent of `head -5`. -n mutes default output, the range address picks lines 1 through 5.
Input
a
b
c
d
e
f
g
Output
a
b
c
d
e
Examples
sed -n '1,5p' file
sed '5q' file # quit after line 5, even faster
sed '5q' file
Print the first 5 lines then quit. Faster than a range on huge files because sed stops reading after line 5.
Input
(file with 1M lines)
Output
(first 5 lines only)
Examples
sed '10q' big.log
sed '/READY/q' boot.log # quit at first READY
sed -n '2~3p' file
GNU step address: print line 2, then every 3rd line after (2, 5, 8 …). The `first~step` form is a GNU extension.
Input
l1
l2
l3
l4
l5
l6
l7
l8
Output
l2
l5
l8
⚠ Common pitfall: The `~` step address is GNU-only. BSD/macOS sed rejects it; use awk `NR%3==2` for portability.
Examples
sed -n '1~2p' file # odd lines
sed -n '0~2p' file # even lines (GNU)
sed '2,4d' file
Delete a line range (2 through 4) and print the rest.
Input
a
b
c
d
e
Output
a
e
Examples
sed '1,10d' file # drop first 10 lines
sed '2,$d' file # keep only line 1
sed -n 'p' file
Print every line once. With -n the default print is off, so `p` restores it — equivalent to `cat`.
Input
a
b
Output
a
b
⚠ Common pitfall: Drop the -n and `sed p` prints every line TWICE — default print plus the explicit p. A classic accident.
Examples
sed -n 'p' file # = cat
sed 'p' file # every line doubled
sed 's/old/new/I' file
Case-INSENSITIVE substitution with the I flag (GNU). Matches Old, OLD, old all the same.
Input
Old OLD old
Output
new new new
⚠ Common pitfall: The I flag is GNU sed. BSD/macOS does not support it — fall back to a character class like `s/[Oo]ld/new/g`.
Examples
sed 's/error/ERR/Ig' app.log
sed 's/.*/[&]/' file
Wrap each whole line in brackets. `&` in the replacement means "the entire matched text".
Input
hello
world
Output
[hello]
[world]
Examples
sed 's/[0-9]*/<&>/' file # bracket the leading number
sed 's/\(.*\)/\1\1/' file
Duplicate the content of each line with a back-reference. `\(.*\)` captures the line, `\1\1` prints it twice.
Input
ab
Output
abab
Examples
sed -E 's/(.*)/\1 \1/' file # space between copies, ERE
sed -n '/foo/,+2p' file
Print the line matching /foo/ plus the next 2 lines. The `+N` relative range is a GNU extension.
Input
a
foo
b
c
d
Output
foo
b
c
⚠ Common pitfall: The `addr,+N` form is GNU-only. On BSD use `sed -n "/foo/{N;N;p;}"` to grab a fixed number of following lines.
Examples
grep -A2 foo file # the grep equivalent
sed '/foo/!d' file
Keep only lines matching /foo/ by deleting the rest. The `!` negates the address, so non-matching lines get deleted.
Input
foo 1
bar 2
foo 3
Output
foo 1
foo 3
Examples
sed '/^#/!d' config # keep only comment lines
sed 's/^[ \t]*//' file
Strip LEADING whitespace from each line (left-trim). Pairs with the trailing-whitespace trim.
Input
hi
bye
Output
hi
bye
Examples
sed -E 's/^[[:space:]]+//' file # POSIX class, portable
sed -n '/foo/I p' file
Print lines matching /foo/ case-insensitively (GNU I address modifier).
Input
Foo
bar
FOO
Output
Foo
FOO
Examples
sed -n '/error/Ip' app.log
sed · Advanced (24)
sed -i 's/old/new/g' file
Edit the file IN PLACE — overwrites the original. GNU sed syntax.
⚠ Common pitfall: On macOS / BSD this fails. BSD sed needs an extension argument: `sed -i "" "s/a/b/" file` (empty string) or `sed -i.bak`. Portable: `sed -i.bak` works everywhere.
Examples
sed -i 's/foo/bar/g' file.txt
sed -i.bak 's/foo/bar/g' file.txt # portable
sed -i '' 's/old/new/g' file
BSD/macOS in-place edit. The `""` is the (empty) backup extension and is REQUIRED on macOS.
Input
hello old world
Output
(file rewritten to: hello new world)
Examples
sed -i '' 's/http:/https:/g' index.html
sed -n '/start/,/end/p' file
Regex address range — print lines from the first /start/ match to the next /end/ match.
Input
a
start
b
c
end
d
Output
start
b
c
end
Examples
sed -n '/BEGIN CERTIFICATE/,/END CERTIFICATE/p' chain.pem
sed -n '/pattern/{N;p;}' file
When line matches /pattern/, append the next line into pattern space with N, then print both as one chunk.
Examples
sed -n '/ERROR/{N;p;}' app.log # show ERROR plus the next line
sed 'N;s/\n/ /' file
Join every pair of lines with a space — read 2 lines into pattern space (N) then replace the embedded newline.
Input
name
Lei
role
dev
Output
name Lei
role dev
Examples
sed 'N;s/\n/ /' two-line-records.txt
sed '/start/,/end/{//!d}' file
Delete the BODY of a block, keeping the markers. `//!d` means "delete every line that does NOT match the most recent regex".
Examples
sed '/^BEGIN/,/^END/{//!d}' file
sed '1!G;h;$!d' file
Classic sed: reverse the file line by line using hold space (h, G).
Input
1
2
3
Output
3
2
1
Examples
sed '1!G;h;$!d' file # like `tac`
sed -e 's/a/b/' -e 's/c/d/' file
Run multiple substitutions in one pass with -e. Order matters.
Examples
sed -e 's/foo/bar/g' -e 's/baz/qux/g' file
sed -f script.sed file
Run sed commands from a file (one command per line). Easier to version-control complex pipelines.
Examples
sed -f rewrites.sed input.txt > output.txt
sed 'H;1h;$!d;x;s/\n/, /g' file
Collapse every line of the file into a single comma-separated row (hold-space accumulator pattern).
Input
a
b
c
Output
a, b, c
Examples
sed 'H;1h;$!d;x;s/\n/, /g' names.txt
sed -E 's|http://([^/]+)/|https://\1/|g' file
Use | as the delimiter so you do not have to escape slashes in URLs. Back-reference \1 keeps the host.
Input
http://example.com/page
Output
https://example.com/page
⚠ Common pitfall: sed picks the delimiter from whatever follows `s`. Pick anything not in your data: |, #, !, @ are common.
Examples
sed 's|/usr/local|/opt|g' paths.conf
sed -i.bak 's/old/new/g' *.md
Edit every .md in the directory in place, leaving .md.bak backups. Portable across GNU and BSD.
⚠ Common pitfall: If the glob expands to many files, the backup count explodes. Clean them with `rm *.md.bak` after verifying the rewrite.
Examples
sed -i.bak 's/2025/2026/g' docs/*.md && rm docs/*.md.bak
sed ':a;N;$!ba;s/\n/ /g' file
Read the whole file into pattern space (loop :a / N / branch ba until last line) then replace all newlines with spaces — collapse to one line.
Input
a
b
c
Output
a b c
Examples
sed ':a;N;$!ba;s/\n/,/g' file # comma-join the whole file
sed -E 's/([0-9]{4})-([0-9]{2})-([0-9]{2})/\3\/\2\/\1/' file
Reformat ISO dates (YYYY-MM-DD) to DD/MM/YYYY using three capture groups and back-references.
Input
2026-05-30
Output
30/05/2026
Examples
sed -E 's/(....)-(..)-(..)/\2\/\3\/\1/' dates.txt # to MM/DD/YYYY
sed -n 'l' file
Print lines in unambiguous form: tabs show as \t, line ends as $, non-printing bytes as octal escapes. Great for spotting hidden characters.
Input
(line with a tab)
Output
col1\tcol2$
Examples
sed -n 'l' suspicious.txt # reveal tabs and CR
cat -A file # similar idea
sed 's/\r$//' file
Strip trailing carriage returns — convert Windows CRLF line endings to Unix LF.
Input
line\r
Output
line
⚠ Common pitfall: BSD sed does not understand `\r`. On macOS use a literal CR: type `sed $'s/\r$//'` or `tr -d '\r'` instead.
Examples
sed -i 's/\r$//' file.txt # dos2unix, GNU
sed 's/$/\r/' file # unix2dos
sed -n '/foo/{=;p;}' file
For each line matching /foo/, print its line number (=) then the line itself (p) — grep with line numbers, two outputs per hit.
Input
a
foo
b
foo
Output
2
foo
4
foo
Examples
sed -n '/ERROR/{=;p;}' app.log
sed '/^$/{N;/^\n$/D}' file
Squeeze consecutive blank lines down to a single blank line. Reads the next line on a blank, deletes if both are blank, loops with D.
Input
a
b
Output
a
b
Examples
cat -s file # the simpler equivalent on GNU coreutils
sed 'n;d' file
Delete every other line, keeping the odd ones. `n` prints the current line and loads the next, `d` deletes that next line.
Input
1
2
3
4
5
Output
1
3
5
Examples
sed 'n;d' file # keep odd lines
sed '1d;n;d' file # keep even lines
sed -E 's/([a-z])([A-Z])/\1_\2/g' file
Convert camelCase to snake_case-ish by inserting an underscore between a lowercase and an uppercase letter (then lowercase separately).
Input
fooBarBaz
Output
foo_Bar_Baz
Examples
sed -E 's/([a-z])([A-Z])/\1_\2/g' file | sed 's/.*/\L&/' # full snake_case, GNU \L
sed 's/\(.\)/\1\n/g' file
Split each character onto its own line by inserting a newline after every character (GNU sed honors \n in the replacement).
Input
abc
Output
a
b
c
⚠ Common pitfall: A literal `\n` in the replacement is a GNU extension. On BSD insert a real newline with a backslash-newline in the script.
Examples
sed 's/\(.\)/\1\n/g' file # one char per line, GNU
sed '0~2d' file
Delete every even-numbered line (keep odd), using the GNU `first~step` address starting at 0 with step 2.
Input
1
2
3
4
Output
1
3
⚠ Common pitfall: GNU-only address. BSD/macOS needs awk `NR%2` instead.
Examples
sed '1~2d' file # delete odd lines, keep even
sed -E 's/(.)\1+/\1/g' file
Squeeze runs of the SAME character down to one — `(.)` captures a char, `\1+` matches its repeats, replacement keeps one.
Input
aaabbbcccd
Output
abcd
Examples
echo 'heelllooo' | sed -E 's/(.)\1+/\1/g' # helo
sed -e '1{h;d;}' -e '2{H;x;}' file
Swap the first two lines using hold space: stash line 1 (h;d), then on line 2 append it (H) and swap (x).
Input
one
two
three
Output
two
one
three
Examples
sed -e '1{h;d;}' -e '2{H;x;}' file
sed · One-liners (24)
sed '$d' file
Drop the last line of a file. `$` is the address "last line".
Input
a
b
c
d
Output
a
b
c
Examples
sed '$d' file.log
sed -n '$=' file
Count the lines in a file. `=` prints the current line number; `$` limits to the last line.
Input
a
b
c
d
Output
4
Examples
sed -n '$=' file
sed = file | sed 'N;s/\n/\t/'
Add line numbers to a file (poor-man's `nl`). The first sed inserts a number line; the second joins.
Input
a
b
c
Output
1 a
2 b
3 c
Examples
sed = file | sed 'N;s/\n/\t/'
sed -n '/pattern/p' file
Like `grep pattern file` — print only matching lines. Useful when sed is already in your pipeline.
Examples
sed -n '/ERROR/p' app.log
sed -n '/^From: /,/^$/p' mbox
Print each email header block — from the From: line up to the next blank line.
Examples
sed -n '/^From: /,/^$/p' inbox.mbox
sed -n '/foo/=' file
Print line NUMBERS of matches (without the content).
Input
a
foo
b
foo bar
c
Output
2
4
Examples
sed -n '/TODO/=' notes.md
sed 's/^/ /' file
Indent every line by four spaces (useful when pasting into Markdown code blocks).
Input
a
b
Output
a
b
Examples
sed 's/^/ /' snippet.txt
sed 's/[ \t]*$//' file
Strip trailing whitespace from every line — kill those invisible spaces at EOL.
Examples
sed -i 's/[ \t]*$//' src/**/*.py
sed -n '1!G;h;$p' file
Reverse the file line order — same idea as `tac`, but works on BSD where `tac` is missing.
Examples
sed -n '1!G;h;$p' file
sed 'G' file
Double-space a file — append an empty line after every line.
Input
a
b
Output
a
b
Examples
sed 'G' notes.txt
sed -n '/^$/!p' file
Print non-empty lines only — short way to skip blank lines.
Examples
sed -n '/^$/!p' file
sed -e :a -e '$!N;s/\n/ /;ta' file
Join ALL lines of the file into one space-separated line (sed loop using label :a and branch ta).
Examples
sed -e :a -e '$!N;s/\n/ /;ta' lines.txt
sed -n '2p' file
Print just the second line. Swap the number to grab any single line.
Input
a
b
c
Output
b
Examples
sed -n '1p' file # first line
sed -n '3p;7p' file # lines 3 and 7
sed -n '$p' file
Print the last line of a file (a sed `tail -1`). `$` is the last-line address.
Input
a
b
c
Output
c
Examples
sed -n '$p' file
sed 's/^/> /' file
Prefix every line with "> " — quote text like an email reply.
Input
hi
there
Output
> hi
> there
Examples
sed 's/^/> /' quote.txt
sed 's/$/;/' file
Append a semicolon to the end of every line. `$` here is the end-of-line anchor.
Input
a
b
Output
a;
b;
Examples
sed 's/$/,/' col.txt # turn a column into CSV-ish
sed 's/ */ /g' file
Squeeze runs of spaces into a single space — quick whitespace normalizer.
Input
a b c
Output
a b c
Examples
sed -E 's/ +/ /g' file # same with ERE
sed -n '1p;$p' file
Print only the first and last line of a file in one pass.
Input
a
b
c
d
Output
a
d
Examples
sed -n '1p;$p' big.log
sed 's/\t/,/g' file
Convert tabs to commas — a quick TSV-to-CSV when no field contains a comma.
Input
a b c
Output
a,b,c
⚠ Common pitfall: BSD sed does not expand `\t`; on macOS press a literal tab or use `sed $'s/\t/,/g'`.
Examples
sed $'s/\t/,/g' in.tsv > out.csv # portable
sed -n '/^$/=' file
Print the line numbers of all blank lines — handy for finding paragraph breaks.
Input
a
b
c
Output
2
4
5
Examples
sed -n '/^$/=' essay.txt
sed '/foo/r insert.txt' file
After every line matching /foo/, read and insert the entire contents of insert.txt. The `r` command appends a file.
Examples
sed '/<!-- INCLUDE -->/r snippet.html' page.html
sed -n '/foo/,/bar/{/foo/d;/bar/d;p;}' file
Print the lines BETWEEN /foo/ and /bar/, excluding the two boundary lines themselves.
Input
x
foo
A
B
bar
y
Output
A
B
Examples
sed -n '/BEGIN/,/END/{/BEGIN/d;/END/d;p;}' block.txt
sed '$!N;/^\(.*\)\n\1$/!P;D' file
Remove consecutive DUPLICATE lines (a sed `uniq`). Compares each line with the next via a back-reference.
Input
a
a
b
b
b
c
Output
a
b
c
Examples
sed '$!N;/^\(.*\)\n\1$/!P;D' file # = uniq for adjacent dups
sed 's/\(.*\):.*/\1/' file
Keep everything before the LAST colon on each line (greedy `.*` eats up to the final colon).
Input
a:b:c
Output
a:b
Examples
sed 's/:[^:]*$//' file # same: drop after last colon
sed · Common pitfalls (10)
GNU sed -i vs BSD sed -i
GNU `sed -i "…"` works; BSD/macOS `sed -i "…"` requires an extension argument right after -i (use `""` for no backup).
⚠ Common pitfall: A non-portable `sed -i` is the single most common cross-platform script bug. Use `sed -i.bak` everywhere — both GNU and BSD accept it, you can `rm *.bak` after.
Examples
sed -i.bak 's/old/new/g' file # portable
case $(sed --version 2>&1) in *GNU*) SED='sed -i' ;; *) SED="sed -i ''" ;; esac
Regex dialect: BRE vs ERE
sed defaults to BRE (basic regex): +, ?, |, (), {} are LITERAL unless escaped. With -E you get ERE where they are metacharacters.
⚠ Common pitfall: `sed s/foo+/bar/` does NOT match `foooo` — it matches the literal string `foo+`. Either escape `\+` (GNU) or use `sed -E s/foo+/bar/`.
Examples
sed -E 's/(foo)+/bar/' file # works on both GNU and BSD
Slash collision in URLs
When the pattern or replacement contains `/`, switch the delimiter. sed lets you pick almost any character right after `s`.
⚠ Common pitfall: `sed s/http:\/\/a\.com/b.com/g` is unreadable. `sed s|http://a.com|b.com|g` is the same thing — readable.
Examples
sed 's|http://|https://|g' file
sed 's#/var/log#/opt/log#g' config
Greedy match swallows too much
sed regex is greedy and there is no `?` lazy modifier in BRE/ERE. `.*` will grab the LONGEST run, not the shortest.
⚠ Common pitfall: `sed "s/<.*>//" "<a><b>"` deletes the entire `<a><b>` — not just `<a>`. Use `[^>]*` instead: `s/<[^>]*>//`.
Examples
sed 's/<[^>]*>//g' page.html # strip tags, no greediness trap
Backreferences need escaped parens in BRE
In BRE (default sed), capture groups are `\(...\)` and back-references are `\1`. ERE (-E) uses bare `(…)`.
Examples
sed 's/\(foo\)\(bar\)/\2\1/' file # BRE
sed -E 's/(foo)(bar)/\2\1/' file # ERE, clearer
Anchors inside a multiline pattern space
After N pulls a second line into pattern space, `^` and `$` still match only the very start and end — NOT each embedded line. Use `\n` to target line boundaries inside.
⚠ Common pitfall: People expect `s/^/> /g` after N to prefix both lines. It only prefixes the first. Match `\n` to reach the second: `s/\n/\n> /`.
Examples
sed 'N;s/^/> /;s/\n/\n> /' file
Last line has no trailing newline
If the input file does not end in a newline, sed preserves that — the output also lacks a final newline, which can break later tools that expect one.
⚠ Common pitfall: A no-newline-at-EOF file fed to a loop can silently drop the last record. Normalize with `sed -e '$a\' file` (GNU) or `printf '\n' >> file`.
Inside single quotes the shell passes the sed script verbatim, but you cannot put a single quote in it. Close-quote, escape, reopen: `'\''`.
⚠ Common pitfall: To replace a straight quote you write a four-char dance: `sed 's/x/'\''/g'`. Or switch the script to double quotes and escape `$` and backslashes instead.
Examples
sed "s/x/'/g" file # double-quote the whole script
sed is line-oriented, not whole-file
By default sed processes one line at a time, so a regex cannot span a newline unless you first pull more lines into pattern space with N or a loop.
⚠ Common pitfall: `sed "s/foo\nbar/X/"` never matches by default because foo and bar are on different lines. Slurp the file first: `sed ":a;N;$!ba;s/foo\nbar/X/"`.
Examples
sed ':a;N;$!ba;s/foo\nbar/X/g' file # cross-line match
Special chars in the REPLACEMENT side
In the replacement, `&`, `\`, and the delimiter are special. A literal ampersand must be escaped as `\&`, or `&` re-inserts the whole match.
⚠ Common pitfall: `sed "s/price/price & tax/"` becomes "price price tax" — the bare & expands. Escape it: `s/price/price \& tax/`.
Examples
sed 's/x/A \& B/' file # literal ampersand
awk · Basics (25)
awk '{ print $1 }' file
Print the first field of every line. Fields are split on whitespace by default.
Input
alice 30 dev
bob 28 ops
Output
alice
bob
Examples
awk '{ print $1 }' /etc/passwd # actually need -F:
ls -l | awk '{ print $9 }'
awk '{ print $NF }' file
Print the LAST field of every line. NF is the number-of-fields variable.
Input
a b c
1 2 3 4
Output
c
4
Examples
ls -l | awk '{ print $NF }' # filenames
awk 'NR==5' file
Print line 5 only. NR is the running record number (= line number for default RS).
Input
a
b
c
d
e
f
Output
e
Examples
awk 'NR==5' file
awk 'NR>=10 && NR<=20' file # range
awk 'END { print NR }' file
Count lines (equivalent to `wc -l`) — print the final value of NR in the END block.
Input
a
b
c
Output
3
Examples
awk 'END { print NR }' file
awk -F, '{ print $2 }' file.csv
Use `,` as the field separator (CSV) and print column 2. -F sets FS at startup.
Input
alice,30,dev
bob,28,ops
Output
30
28
⚠ Common pitfall: -F splits on a LITERAL char by default; -F"\t" needs the quotes. For regex separators use -F"[,;]" (with -E semantics inside awk).
Examples
awk -F, '{ print $1, $3 }' data.csv
awk -F: '{ print $1 }' /etc/passwd
awk 'BEGIN { print "hi" }'
Run an action before any input. Useful for headers, constants, or as a stand-alone calculator with no input file.
Output
hi
Examples
awk 'BEGIN { print 2+2 }' # 4
awk 'BEGIN { for(i=1;i<=5;i++) print i }'
awk '/pattern/ { print }' file
Print lines matching a regex (essentially `grep pattern`). The default action is print, so `awk /pattern/` works too.
Examples
awk '/ERROR/' app.log
awk '/^200/ { print $7 }' access.log
awk '/start/,/end/' file
Range pattern — print every line from the first `/start/` match through the next `/end/` match (inclusive).
Examples
awk '/BEGIN/,/END/' file
awk '{ printf "%-10s %5d\n", $1, $2 }' file
Formatted output with printf — left-pad column 1 to width 10, right-pad column 2 as a 5-wide integer.
Swap the first and last fields of each line using a temp variable, then default-rebuild and print.
Input
a b c
1 2 3
Output
c b a
3 2 1
Examples
awk '{t=$1;$1=$NF;$NF=t;print}' file
awk · Common pitfalls (10)
Floating-point precision (IEEE 754)
awk numbers are C doubles. `awk "BEGIN{print 0.1+0.2}"` prints 0.3 because of awk default OFMT — but `printf "%.17f\n", 0.1+0.2` reveals 0.30000000000000004.
⚠ Common pitfall: Never compare floats with ==. Sum, then compare with a tolerance: `if (s > target - 0.001 && s < target + 0.001)`. For exact money math use integers (cents) and divide at the end.
awk silently treats field values as either string or number depending on context. To force numeric (e.g. for sorting via comparison), add 0: `$3+0 > 100`.
⚠ Common pitfall: `awk "$3 > 100" data.txt` works if column 3 looks like a number, but `awk "$3 > 100" data-with-units.txt` (rows like "42MB") silently does string comparison and misleads you.
Examples
df -h | awk '$5+0 > 80' # force numeric on "80%"
gawk vs awk vs mawk
There are three common awks. gawk (GNU) has the most features (true regex, --csv, networking). mawk is the fastest. BSD awk on macOS is the most limited.
⚠ Common pitfall: `gsub(/regex/, "x", arr[i])` works on gawk but not BSD awk. Scripts that use `length(array)` need gawk. Test with `awk --version` to know which one you have.
Examples
awk --version 2>&1 | head -1
brew install gawk # macOS users wanting gawk
Uninitialized variables are 0 and empty
An unset awk variable is both numeric 0 and the empty string, chosen by context. Convenient for counters, but it hides typos in variable names silently.
⚠ Common pitfall: Typo a counter as `coutn[$1]++` and awk happily creates a new array — no error, just a wrong answer. There is no "undefined variable" warning unless you run `gawk --lint`.
Examples
gawk --lint '{c[$1]++} END{for(k in c)print k,c[k]}' file
print vs printf newline
`print` appends ORS (a newline by default); `printf` does NOT add anything — you must include `\n` yourself or output runs together.
⚠ Common pitfall: `awk "{printf \$1}"` glues every field-1 onto one long line with no separators. Add the newline: `printf "%s\n", $1`.
Examples
awk '{printf "%s\n", $1}' file # remember the \n
-F with a regex vs a literal
A single-character -F is taken literally; a multi-character -F value is treated as a regex. So `-F.` splits on ANY char, not on a literal dot.
⚠ Common pitfall: `awk -F. "{print \$1}"` on `a.b.c` prints an empty field because `.` is the regex "any char". Escape it: `-F"\\."` or `-F"[.]"`.
Examples
awk -F'[.]' '{print $1}' host.example.com # split on literal dot
Leading-zero numbers and octal
Field values like "010" are treated as decimal 10 in arithmetic, but string-vs-number coercion around leading zeros and bases can surprise you, especially with strtonum().
⚠ Common pitfall: gawk `strtonum("010")` returns 8 (octal) while `"010"+0` returns 10. Mixing the two on the same data gives inconsistent results. Pick one coercion and stick with it.
Examples
awk 'BEGIN{print "010"+0}' # 10
gawk 'BEGIN{print strtonum("010")}' # 8
Modifying $0 resplits the fields
Assigning to $0 re-runs field splitting with the current FS, and assigning to any field rebuilds $0 with OFS. The two can clobber each other if you are not careful about order.
⚠ Common pitfall: If you do `$0 = $0 "x"; print $3`, the fields are recomputed from the new $0 — your earlier field edits may vanish. Finish field edits before touching $0 wholesale.
Searchable awk + sed cheat sheet with 80+ one-liners covering
every shell text-processing task you actually hit on a Tuesday
morning. Four sections per tool. sed basics: s/// substitution,
the global g flag, the N flag for "replace the Nth match",
address ranges, d delete, p print, i insert, a append, c change,
y transliteration. sed advanced: hold space (h H g G x), pattern
space tricks, branching (b t :label), multi-file edits, GNU vs
BSD -i and the macOS '' trap, in-place backups, BRE vs ERE
regex. awk basics: NF NR $0 $1 $2, BEGIN and END blocks,
printf format strings, FS / OFS / RS / ORS, pattern { action }
flow, /regex/ patterns, range patterns, -F separator, -v var.
awk advanced: associative arrays, split(), substr(), gsub(),
length(), toupper/tolower(), accumulator patterns (sum,
average, max, min), uniq with arrays, two-file joins via
FNR==NR, formatting, and pipelines into sort / uniq / grep.
Common one-liners: delete blank lines, drop line N or last,
print lines 10 to 20, sum a column, average a column, count
unique values, swap two columns, extract field 3 from CSV,
drop duplicates while preserving order. Plus a pitfalls
section: GNU sed vs BSD sed -i differ (macOS needs "" after
-i); awk floats are doubles so 0.1+0.2 is 0.30000000000000004;
regex dialect (BRE vs ERE) bites when you bring a perl
pattern; sed slash collision in URLs forces you to switch
delimiters (s|http://||); awk OFS does NOT apply unless you
reassign a field. Every entry: bilingual EN/ZH descriptions,
real input/output, the pitfall, and at least one copy-ready
example. Search filters across command, description, pitfall,
input/output, and example at once; tool chips scope to awk vs
sed; category chips scope to basic / advanced / one-liner /
pitfall; one-click copy. 100% client-side, runs in your tab.
Tool details
Input
Text
The page exposes text boxes, numeric controls, file pickers, or structured inputs depending on the tool.
Output
Live result + Copy
The result area focuses on usable output, with copy, download, or preview actions when supported.
Privacy
Browser-side processing
The main tool logic does not call an external API, so inputs normally stay in the current tab.
Save / share
Shareable URL state
Key settings are encoded in the URL so another person can reopen the same setup.
Performance budget
Initial JS <= 25 KB
No WASM budget is declared, keeping the tool quick to open on mobile.
Best fit
Developer & DevOps · Developer
Category and role tags drive related tools, internal links, and quick fit checks.
How to use
1
1. Input
Paste or drop your content into the tool panel.
2
2. Process
Click the button. All processing is local in your browser.
3
3. Copy / Download
Copy the result or download to disk in one click.
How awk + sed Cheatsheet fits into your work
Use it in the small gaps between coding, reviewing, debugging, and shipping.
Developer jobs
Formatting, validating, shrinking, or inspecting code-adjacent text.
Preparing snippets for documentation, tickets, commits, or handoff.
Checking a small payload quickly without switching tools.
Developer checks
Run irreversible transforms like minify or obfuscate on a copy.
Keep secrets out of pasted snippets unless the tool explicitly stays local.
Use your normal tests or linter before shipping transformed code.
Good next steps
These links move the current task into a more complete workflow.
Rename a function across 300 files before a release freeze
Your team renamed `getUser` to `fetchUser` and CI is red in 312 source
files. You preview with `rg -l 'getUser' | xargs sed 's/getUser/fetchUser/g' | diff`
first, then run the in-place pass. The cheat sheet's multi-file sed
entry and the macOS `-i ''` pitfall save you from the silent no-op that
would have shipped half the rename.
Tally HTTP status codes from a 2 GB access log on a jump host
Production is throwing 500s and you have shell access to one air-gapped
box, no Python, no internet. You copy the group-by one-liner
`awk '{ c[$9]++ } END { for (k in c) print k, c[k] }' access.log` and
learn in 4 seconds that 503s spiked from 12 to 8,400. The associative
array entry is exactly the pattern you could not have written from memory.
Pull the third column out of a messy CSV export for a finance report
A vendor hands you a 50,000-row CSV and you need column 3 summed for the
quarterly close. You grab `awk -F, '{ s += $3 } END { print s }' data.csv`,
then hit the quoted-comma gotcha the FAQ warns about and switch to
`gawk --csv`. The cheat sheet routed you around a wrong total before
anyone signed off on it.
Strip blank lines and comments from a config before diffing two servers
Two nginx boxes drift and the configs differ only in whitespace and
comments. You normalize both with `awk 'NF && $1 !~ /^#/' a.conf` and
`... b.conf`, then diff. The four-character `awk 'NF'` idiom turns a
noisy 400-line diff into the three real lines that actually changed.
Common pitfalls
Forgetting the empty quotes on macOS. `sed -i 's/a/b/' f` does nothing on BSD sed; you need `sed -i '' 's/a/b/' f` or the portable `sed -i.bak '...'`.
Trusting `awk -F,` on real CSV. A field like `"Smith, John"` splits on the inner comma. Use `gawk --csv` (gawk 5.3+) or `mlr` when quotes can hold commas.
Expecting OFS to reformat output by itself. `awk '{ OFS="," } 1'` keeps the original spaces; you must touch a field, e.g. `awk '{ $1=$1 } 1'`, to trigger the rebuild.
Privacy
Every one-liner, the search box, the awk/sed and category chips, and the
copy button run entirely in your browser against an in-memory array. No
command, no search term, and nothing you copy is sent to a server or written
into the page URL. Open DevTools then Network and type: you will see zero
outbound requests. It works behind a corporate proxy, on a plane, or on an
air-gapped jump host, which is exactly where you reach for awk and sed.
FAQ
Related tools
Hand-picked utilities that pair well with this one.