Working with text

grep, less, head/tail, pipes and redirection — composing small tools into exactly the answer you need.

Looking at files

less app.log       # space to page, / to search, q to quit
head -20 app.log
tail -50 app.log
tail -f app.log    # follow - watch new lines arrive

nl file.txt        # numbered lines
wc -l file.txt     # count lines
💡
Learn less before anything else: it never loads a whole huge file into memory, unlike opening it in an editor.

Searching with grep

grep 'ERROR' app.log
grep -i 'error' app.log          # case-insensitive
grep -n 'timeout' app.log        # include line numbers
grep -r 'TODO' src/              # recursive
grep -v 'DEBUG' app.log          # invert: lines NOT matching
grep -E '4[0-9]{2}|5[0-9]{2}' access.log   # extended regex
grep -c 'ERROR' app.log          # count matching lines
FlagEffect
-iIgnore case
-nShow line numbers
-rRecursive into directories
-vInvert match
-EExtended regular expressions
-A/-B/-C nShow after/before/around context

Pipes and redirection

cat app.log | grep ERROR | wc -l      # count errors
ps aux | grep node | grep -v grep
history | awk '{print $2}' | sort | uniq -c | sort -rn | head

grep ERROR app.log > errors.txt       # overwrite
grep ERROR app.log >> errors.txt      # append
command 2> errors.txt                 # stderr only
command > out.txt 2>&1                # both together

| sends one program's output into the next. File descriptor 1 is stdout, 2 is stderr — that is why 2>&1 means 'stderr, to wherever stdout is going'.

Reshaping output

cut -d',' -f1,3 data.csv       # select fields
sort -t',' -k2 -n data.csv     # numeric sort on field 2
uniq -c                        # count adjacent duplicates (sort first!)
tr 'a-z' 'A-Z'                 # translate characters
sed -n '10,20p' file           # print lines 10-20
awk -F',' '{ sum += $2 } END { print sum }' data.csv
💡
uniq only collapses adjacent duplicates — always sort first. This trips up almost everyone once.

FAQ

How do I search inside files recursively and interactively?
grep -r for quick answers; ripgrep (rg) for speed on larger trees, since it respects ignore files by default.
tail -f vs less +F?
tail -f simply follows; less +F lets you stop with Ctrl-C and scroll back through history before resuming.

Shell basics and navigation Processes, ports and jobs

Last refreshed 2026-09-17.