Shell Toolkit (Cheatsheet)
Context: FIT1043_MOC, FIT2014_MOC Β· navigate β inspect β search/count β sort β cut columns β pipe β compress β awk β sed/tr/regex β hand off Β· depth in Unix Shell (Bash); text-transform detail in Text Processing with sed and tr Β· FIT2014 = Lab 0 tooling
Read protocol: scan tables β attempt the practice blank β follow the pattern-note link only where you failed.
Quick Revision
- π― Objective: explore/clean a huge text/CSV file from the command line without loading it into memory β chain small tools with pipes, then hand the reduced file to R/Python.
- β‘ Key Constraint: the pipe
|is buffered + line-at-a-time β memory stays bounded so it scales past RAM;>overwrites a file,|feeds the next program β never confuse them.
π§© Pipeline Anatomy (execution order)
cat big.csv.gz | gunzip | awk -F',' 'NR>1 {print $6,$14}' | sort -n | head
# ββsourceβββ βdecompβ βββselect cols, skip headerβββ βnumericβ βpeekβ
# reads LβR; each stage streams rows to the next as needed (nothing fully in memory)- Order β
source β transform β filter β sort β view/save; put cheap filters early (less data flows downstream). - Save instead of view β replace the final
head/lesswith> out.txtto persist the result.
π Navigate & files
| Tool | Micro-syntax | Job / gotcha |
|---|---|---|
cd | cd dir Β· cd .. (up) Β· cd (home) | change directory |
ls | ls Β· ls -l (long) Β· ls -a (hidden) | list directory |
pwd | pwd | print working directory |
cp / mv | cp src dst Β· mv src dst | copy / move-rename |
mkdir / rm | mkdir d Β· rm f Β· rm -r d | make dir / remove (β no undo) |
π Inspect / read
| Tool | Micro-syntax | Job / gotcha |
|---|---|---|
less | less file β space/ββ page, /kw search, shift+g end, q quit | reads only the start β instant on huge files |
cat | cat file | dump whole file (or concatenate) |
head / tail | head -n 20 file Β· tail -n 20 file | first / last N lines (default 10) |
wc | wc -l file (lines) Β· wc (lines/words/chars) | β must read the whole file β slow on huge files |
π Search & count
| Tool | Micro-syntax | Job / gotcha |
|---|---|---|
grep | grep "elephant" file | print lines containing the pattern |
grep -c | grep -c "kw" file | count matching lines (= grep β¦ | wc -l) |
grep -i / -v | grep -i "kw" Β· grep -v "kw" | case-insensitive Β· invert (non-matching) |
| count matches | grep "kw" file | wc -l (pipe to count) | classic filter-then-count |
π’ Sort
| Tool | Micro-syntax | Job / gotcha |
|---|---|---|
sort | sort file | alphabetical (default) |
sort -n | sort -n file | numeric (else 10 sorts before 2) |
sort -r | sort -r file | reverse order |
sort -k | sort -k2,2 file | sort by column 2 |
sort -t | sort -t',' -k2,2n | set delimiter , + numeric key |
uniq | sort file | uniq -c | count duplicates (β needs sorted input) |
βοΈ Columns
| Tool | Micro-syntax | Job / gotcha |
|---|---|---|
cut -f | cut -f 3 file | column 3 β assumes tab delimiter |
cut -d | cut -d',' -f 3 file | set delimiter to comma |
awk cols | awk -F',' '{print $6,$7,$14}' | columns 6/7/14; -F',' = comma delimiter; $0 = whole line |
π§ awk power (one line at a time β scales)
| Task | Micro-syntax | Note |
|---|---|---|
| set delimiter | awk -F',' 'β¦' | -F = field separator |
| row-range filter | awk -F',' 'NR>1000 && NR<=1500 {print $6}' | NR = current line number |
| skip header | awk -F',' 'NR>1 {print $6}' | drop line 1 |
| random sample | awk 'rand()<1/100 {print $0}' | keep ~1% of rows |
| value filter (+header) | awk -F',' '$22=="\"California\"" || NR==1 {print $6}' | escape embedded quotes \" |
π Pipes, redirect, wildcards, compression
| Tool | Micro-syntax | Job / gotcha |
|---|---|---|
| pipe | prog1 | prog2 | stream output of one into the next |
| redirect | β¦ > out.txt (overwrite) Β· β¦ >> out.txt (append) | β > replaces the file |
wildcard * | book*.txt | match any characters |
| bracket range | book[1-5].txt | match a range (books 1β5 only) |
gunzip | gunzip file.gz (in place) Β· cat f.gz | gunzip | β¦ (stream) | decompress .gz |
unzip -p | unzip -p file.zip | β¦ | stream a zip to a pipe β no huge temp file |
| background | myprogram & | run in background; scripts can be shell programs |
π€ Hand-off & setup
| Task | Micro-syntax | Note |
|---|---|---|
| shell β R | awk β¦ > out.txt then in R: df <- read.table('out.txt', header=TRUE) | reduce first, analyse in R |
| Windows setup | install Cygwin | provides a Unix shell on Windows |
| macOS (Big Sur+) | chsh -s /bin/bash | default is now zsh; switch to bash |
π€ Text transform β sed / tr / grep-regex (FIT2014 β details β Text Processing with sed and tr)
| Tool | Micro-syntax | Job / gotcha |
|---|---|---|
sed substitute | sed 's/pat/rep/' file | first match per line; file unchanged (stdout) |
sed global | sed 's/pat/rep/g' file | g = every match on the line |
sed backref | sed 's/2\([0-9]*\)/3\1/' | \(...\) captures, \1..\9 reuse in replacement |
sed delete chars | sed 's/[^a-zA-Z]//g' | replace-with-nothing = delete |
| char class | [aeiou] Β· [a-z] Β· [^a-z] | set Β· range (ASCII) Β· complement (^ first) |
| anchors | ^pat Β· pat$ Β· ^pat$ | starts / ends / whole line |
tr map | tr 'A-Z' 'a-z' | per-character map (not words) |
tr -d / -s | tr -d 'aeiou' Β· tr -s ' ' | delete listed Β· squeeze runs to one |
grep regex | grep '[aeiou][aeiou]' f Β· grep '^a.*b$' f | grep patterns are regexes (Regular Expressions) |
(β POSIX BRE: grouping/repetition are escaped β \(...\), \{n\}; bare () {} are literal. Opposite of the theory notation.)
βοΈ Integration Practice
Practice 1: From gzipped
air.csv.gz(comma-delimited, header on line 1), print the 10 largest values of column 14, ignoring the header.Reference solution
cat air.csv.gz | gunzip | awk -F',' 'NR>1 {print $14}' | sort -nr | head
- Key move: decompress β
awkskips header + selects col βsort -nr(numeric, reverse) βhead. Filter (NR>1) sits early so less data flows on.
Practice 2: Count how many rows in
data.csvhave "ERROR" in them, then save just those rows toerrors.txt.Reference solution
grep -c "ERROR" data.csv # count matching rows grep "ERROR" data.csv > errors.txt # save matching rows
- Key move:
grep -ccounts in one step;>persists the filtered rows (use>>to append instead of overwrite).
β οΈ Common Mistakes
- π‘
>overwrites,|chains β redirect replaces the target file; pipe feeds the next program. - π‘ Mind the delimiter β
cut -fassumes tab; for CSV useawk -F','orcut -d','. Check the real delimiter first (/<tab>search inless). - π‘
wc/sort/uniqread the whole file β slow + memory-heavy on huge files;less/headonly read the start β instant. Put cheap filters before them. - π‘
sortis alphabetical by default β add-nfor numbers, anduniqonly collapses adjacent duplicates (sosort | uniq).