Bash
Moving around, wrangling text, and writing small scripts that don't fall over.
Files & navigation
ls -lah- List everything, human-readable sizes
cd -- Jump back to the previous directory
mkdir -p a/b/c- Create nested folders in one go
cp -r src dst- Copy a directory recursively
find . -name "*.log"- Find files by name pattern
du -sh *- Size of each item in the current folder
Pipes & redirection
cmd > out.txt- Overwrite file with stdout
cmd >> out.txt- Append stdout to file
cmd 2>&1- Send stderr to wherever stdout goes
cmd1 | cmd2- Feed output of one command into another
cmd | tee log.txt- Print and save at the same time
cmd < input.txt- Read stdin from a file
Text processing
grep -rn "TODO" src/- Recursive search with line numbers
sed -i 's/foo/bar/g' f- Replace in place (macOS:
sed -i '') awk '{print $2}'- Print the second column
sort | uniq -c | sort -rn- Count occurrences, most frequent first
cut -d, -f1,3- Columns 1 and 3 of a CSV
tail -f app.log- Follow a log file as it grows
Processes
cmd &- Run in the background
jobs/fg %1- List background jobs / bring one forward
ps aux | grep node- Find a running process
kill -9 <pid>- Force-terminate a process
lsof -i :3000- What is listening on port 3000?
Keyboard shortcuts
Ctrl + R- Search command history
Ctrl + A/Ctrl + E- Start / end of line
Ctrl + U/Ctrl + K- Cut to start / end of line
Ctrl + L- Clear the screen
!!- Repeat last command (
sudo !!)
Variables & expansion
${VAR:-default}- Use default if VAR is unset
${#VAR}- Length of the string
${FILE%.txt}- Strip suffix
$(cmd)- Substitute a command's output
$?- Exit code of the last command
Tip: Start every script with
set -euo pipefail so it stops on errors, unset variables and failed pipes instead of charging ahead.Script skeleton
#!/usr/bin/env bash set -euo pipefail usage() { echo "usage: $0 <input-dir>"; exit 1; } [[ $# -eq 1 ]] || usage dir="$1" for f in "$dir"/*.csv; do [[ -e "$f" ]] || continue echo "processing $(basename "$f")" wc -l < "$f" done