Skip to content

~/avetyan.com/cheatsheets

Cheat sheets

Text processing one-liners

Slice and reshape text on the command line with cut, tr, paste, column, comm, join, sort and awk: columns, CSV, joins and set operations.

3 min read


Columns

bash
cut -d: -f1,7 /etc/passwd               # fields 1 and 7, colon-separated
cut -c1-10 file                         # characters 1 to 10
awk '{print $1, $NF}' file              # first and last field, any whitespace
awk -F, '{print $2}' data.csv
awk -F'\t' -v OFS=, '{$1=$1; print}' data.tsv   # TSV to CSV

cut needs a single delimiter character; for runs of spaces use awk, or squeeze them with tr -s ' ' first.

Characters

bash
tr 'a-z' 'A-Z' < file                   # upper case
tr -d '\r' < windows.txt > unix.txt     # strip CR from CRLF
tr -s ' ' < file                        # squeeze repeated spaces
tr ',' '\n' <<< "a,b,c"                 # one item per line
tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 24; echo   # random string

Join lines

bash
paste -sd, list.txt                     # all lines into one, comma-separated
paste names.txt ages.txt                # side by side, tab-separated
paste -d: - - < pairs.txt               # every two lines into one
xargs -n3 < words.txt                   # three words per line

Align output

bash
column -t -s, data.csv                  # CSV as a table
mount | column -t
column -t -s: /etc/passwd | less -S
printf '%-20s %8s\n' name size

Sort

FlagWhat it does
bash
sort -t, -k3,3nr data.csv               # CSV by column 3, numeric, descending
sort -k2,2 -k1,1n file                  # by field 2, then numeric field 1
du -sh * | sort -h

Set operations

bash
sort -u a.txt > a.s; sort -u b.txt > b.s
comm -12 a.s b.s                        # in both
comm -23 a.s b.s                        # only in a
comm -13 a.s b.s                        # only in b
sort a.txt b.txt | uniq -d              # in both (no duplicates within a file)
sort a.txt b.txt | uniq -u              # in exactly one

comm and join need sorted input, or they silently give wrong answers.

Join two files

bash
# users.txt: id name     orders.txt: id total
join <(sort users.txt) <(sort orders.txt)
join -t, -1 1 -2 2 <(sort -t, -k1,1 users.csv) <(sort -t, -k2,2 orders.csv)
join -a1 users.txt orders.txt           # keep unmatched lines from the first file

Sums and stats

bash
awk '{s += $1} END {print s}' numbers.txt
awk '{s += $1; n++} END {print s/n}' numbers.txt
awk -F, 'NR>1 {sum[$1] += $3} END {for (k in sum) print k, sum[k]}' sales.csv
sort -n numbers.txt | awk '{a[NR]=$1} END {print a[int(NR/2)+1]}'   # median (upper middle for an even count)

Small helpers

bash
nl -ba file                             # number every line
rev file                                # reverse each line
fold -w 80 -s long.txt                  # wrap at 80, on spaces
expand -t 4 file                        # tabs to spaces
head -n 20 file | tail -n 5             # lines 16–20
sed -n '16,20p' file                    # the same
split -l 100000 big.csv part_           # into 100k-line files
wc -lwc file                            # lines, words, bytes

Keep in mind

  • sort order depends on the locale. Set LC_ALL=C for byte order, speed and repeatable results in scripts.
  • Quoted CSV fields with commas inside break cut and plain awk -F,. Use a CSV-aware tool (mlr, csvkit, Python) for real CSV.

Comments

Sign in with Google, GitHub or Facebook to comment.

Loading comments…