LFCA 18 ๐ง Viewing Files โ cat, less, head, tail
Viewing files is the most frequent thing you do in a shell. Unlike deletion (LFCA 17), it’s read-only โ no undo needed, no data loss possible. But the wrong tool wastes time: cat on a 2 GB log file floods your terminal with millions of lines; less on a three-line config is overkill. Four commands cover the spectrum: cat dumps entire files (or concatenates them), less pages through large files with search and navigation, head shows the first lines, and tail shows the last โ and with -f, streams new lines as they arrive. This chapter covers when each is appropriate, the flags that matter, and the habits that prevent terminal flooding.
Key point: cat is for small files and pipelines, not for reading. less is the default viewer for anything you’ll read interactively โ it loads one screen at a time and lets you search. head and tail slice the beginning and end of files without opening the whole thing. tail -f is the log-monitoring command. All four read from standard input when no file is given, which makes them composable in pipelines.
What cat does
cat concatenates files and prints them to standard output . With one file, it displays the contents. With multiple files, it prints them in sequence. With no file (or -), it reads from standard input.
$ cat notes.txt
line one
line two
line three
The file appears in the terminal, then the prompt returns. No pager, no interaction. That’s the defining characteristic: cat dumps everything and exits.
Concatenation โ the real purpose:
$ cat part1.txt part2.txt > combined.txt
cat exists to join files. Viewing is a side effect. The name comes from “concatenate,” and in pipelines it chains streams:
$ cat access.log | grep "404" | wc -l
Numbering lines with -n:
$ cat -n script.sh
1 #!/bin/bash
2 echo "hello"
3 exit 0
-n numbers every line; -b numbers only non-blank lines . Useful for referencing specific lines in documentation or debugging.
Showing invisible characters with -A:
$ cat -A config.txt
server=localhost^M$
user=admin$
-A (equivalent to -vET) displays $ at line endings, ^I for tabs, and ^M for carriage returns . This exposes Windows line endings (CRLF) that would otherwise be invisible โ a common source of shell script failures.
Why cat isn’t for reading: When you cat a large file, the terminal scrolls through every line until the end. You see only the last screenful; the rest is history you’d have to scroll back through (if your terminal even keeps it). cat doesn’t pause, doesn’t search, doesn’t navigate. For reading, use less .
Why
cat fileis sometimes still correct: For small files (under a screen),catis faster thanlessโ no pager startup, no keypress to quit. For pipelines,cat file | commandis a valid pattern (thoughcommand < fileorcommand fileoften works too). Know when you’re reading versus when you’re piping.
What less does
less displays a file one screen at a time and waits for you to navigate . It loads only what fits on the screen, so it opens multi-gigabyte files instantly .
$ less /var/log/syslog
The first screen of the file appears. The bottom shows a prompt (:) where you can type commands. Press q to quit.
Why less beats cat for reading:
Problem with cat | less solution |
|---|---|
| Scrolls past content | Pauses at each screenful |
| No search | /pattern searches forward; n repeats |
| Can’t go back | Arrow keys, Page Up/Down, b/Space |
| Terminal fills with output | Exit clears the screen |
Essential navigation:
# Inside less:
/error # search forward for "error"
n # next match
N # previous match
G # go to end of file
g # go to beginning
Space # next page
b # previous page
q # quit
These are documented in the less man page . The search is case-sensitive by default; -i makes it case-insensitive .
Following a growing file with F: Inside less, press F to enter follow mode โ the same behavior as tail -f. New lines appear as they’re written. Press Ctrl+C to stop following and return to normal navigation . This is useful when you’re already in less and realize the file is growing.
Why less is the default viewer: It handles every size. On a small file it behaves like cat with scrolling. On a large file it remains responsive. It can view compressed files (with lesspipe), search within them, and pipe output from other commands (ps aux | less) .
less vs more: more is older and can’t scroll backward. less is the improved version โ the name is a joke: “less is more” . On most systems, less is installed; if not, more is the fallback. For any interactive reading, use less .
Why
lessis faster thancaton large files:lessreads only the portion it needs to display.catreads and prints the entire file, which means the terminal emulator must process and store every line. For a 1 GB log file,catwould freeze your terminal for minutes;lessopens in milliseconds .
What head does
head prints the first 10 lines of a file by default . It’s the “peek at the beginning” command โ useful for headers, config file tops, and checking file type.
$ head /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
...
Ten lines is the default because most file headers fit. For CSV files, the first line is often the column header โ head -1 grabs it.
Controlling the count with -n:
$ head -n 5 access.log
$ head -5 access.log # same
Older versions required -n; modern coreutils accept head -5 . Both work.
Multiple files get headers:
$ head -n 3 a.txt b.txt
==> a.txt <==
alpha
beta
gamma
==> b.txt <==
one
two
three
When more than one file is given, head prints a filename header before each . -q suppresses headers; -v forces them .
Bytes instead of lines with -c:
$ head -c 100 /dev/urandom | xxd
-c outputs the first N bytes. Useful for binary files or when line breaks are unknown .
Why head is safer than cat: For a file you’re unsure about (a log, a binary, a huge config), head shows the first lines without committing to the whole thing. If it’s not what you expected, Ctrl+C is unnecessary โ head already exited.
Why
headis useful in scripts:head -1extracts the first line of a command’s output.command | head -n 1gives you the first result without waiting for the full stream (though the command may still run to completion unless it detects the closed pipe).
What tail does
tail prints the last 10 lines of a file by default . It’s the “what just happened” command โ logs append to the end, so the newest entries are last.
$ tail /var/log/auth.log
Mar 15 10:22:01 host sshd[1234]: Accepted password for alice from 192.168.1.100
Mar 15 10:22:01 host sshd[1234]: pam_unix(sshd:session): session opened for user alice
...
For any file that grows (logs, output files, monitoring data), tail shows the most recent state.
Controlling the count with -n:
$ tail -n 20 syslog
$ tail -20 syslog # same
Following a growing file with -f:
$ tail -f /var/log/syslog
-f (follow) keeps the file open and prints new lines as they’re appended . This is how you monitor a log in real time. Press Ctrl+C to stop.
-f vs -F โ the log rotation problem: By default, tail -f follows the file descriptor. If the file is rotated (renamed and a new file created with the same name), tail keeps following the old file descriptor โ you see nothing new because new lines go to the new file. -F (or --follow=name --retry) follows the name instead, reopening when the file is replaced . For log files that rotate, always use -F.
$ tail -F /var/log/nginx/access.log
tail -n +N โ skip the beginning: The + prefix means “start at line N” rather than “show the last N.”
$ tail -n +2 data.csv
This skips line 1 (the header) and shows the rest . Useful for processing CSV data without the header row.
Why tail -f is the log command: Logs are append-only. To watch events arrive, you need a command that waits for new lines. tail -f does exactly that โ no polling, no re-running. tail -F handles the rotation case.
Why
tailis useful in pipelines:command | tail -n 5shows only the last five lines of output. For a command that prints thousands of lines but you only care about the end (test results, build summaries), this filters without a pager.
Complete Example Session
# ============================================
# PART 1: CAT A SMALL FILE
# ============================================
echo -e "alpha\nbeta\ngamma" > demo.txt
cat demo.txt
# alpha
# beta
# gamma
# ============================================
# PART 2: CAT -N (NUMBER LINES)
# ============================================
cat -n demo.txt
# 1 alpha
# 2 beta
# 3 gamma
# ============================================
# PART 3: CAT -A (SHOW INVISIBLE)
# ============================================
printf "line1\r\nline2\n" > crlf.txt
cat -A crlf.txt
# line1^M$
# line2$
# ============================================
# PART 4: CONCATENATE
# ============================================
echo "one" > a.txt
echo "two" > b.txt
cat a.txt b.txt
# one
# two
cat a.txt b.txt > combined.txt
cat combined.txt
# one
# two
# ============================================
# PART 5: LESS (INTERACTIVE โ SHOW COMMANDS)
# ============================================
# less /etc/services
# (file opens, press q to quit)
# /http โ search for "http"
# n โ next match
# G โ go to end
# g โ go to beginning
# q โ quit
# ============================================
# PART 6: HEAD
# ============================================
seq 1 20 > numbers.txt
head numbers.txt
# 1
# 2
# ...
# 10
head -n 3 numbers.txt
# 1
# 2
# 3
# ============================================
# PART 7: HEAD WITH MULTIPLE FILES
# ============================================
head -n 2 a.txt b.txt
# ==> a.txt <==
# one
#
# ==> b.txt <==
# two
# ============================================
# PART 8: TAIL
# ============================================
tail numbers.txt
# 11
# 12
# ...
# 20
tail -n 3 numbers.txt
# 18
# 19
# 20
# ============================================
# PART 9: TAIL -N +N (SKIP START)
# ============================================
tail -n +18 numbers.txt
# 18
# 19
# 20
# ============================================
# PART 10: TAIL -F (FOLLOW)
# ============================================
# In one terminal:
# tail -f /tmp/live.log
# In another:
# echo "event 1" >> /tmp/live.log
# echo "event 2" >> /tmp/live.log
# (tail shows both lines as they arrive)
# Ctrl+C to stop
# ============================================
# PART 11: PIPELINE COMPOSITION
# ============================================
seq 1 100 | tail -n 5
# 96
# 97
# 98
# 99
# 100
ps aux | head -5
# USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
# root 1 0.0 0.1 167436 11452 ? Ss Mar15 0:03 /sbin/init
# ...
# ============================================
# PART 12: HEAD + TAIL FOR MIDDLE LINES
# ============================================
# Lines 5 through 7 of numbers.txt
head -n 7 numbers.txt | tail -n 3
# 5
# 6
# 7
Each part demonstrates a viewing scenario. The tools compose: head and tail in a pipeline extract a range.
Quick Reference
cat Flags
| Flag | Effect |
|---|---|
| (none) | Print file contents |
-n | Number all lines |
-b | Number non-blank lines |
-A | Show all: $ at end, ^I tabs, ^M CR |
-E | Show $ at line ends |
-T | Show tabs as ^I |
-s | Squeeze multiple blank lines |
-v | Show non-printing characters |
less Commands (Inside Viewer)
| Key | Action |
|---|---|
Space / f | Next page |
b | Previous page |
g | First line |
G | Last line |
/pattern | Search forward |
?pattern | Search backward |
n | Next match |
N | Previous match |
F | Follow (like tail -f) |
q | Quit |
head Flags
| Flag | Effect |
|---|---|
| (none) | First 10 lines |
-n N | First N lines |
-c N | First N bytes |
-q | Suppress filenames |
-v | Always show filenames |
tail Flags
| Flag | Effect |
|---|---|
| (none) | Last 10 lines |
-n N | Last N lines |
-n +N | Start at line N |
-c N | Last N bytes |
-f | Follow descriptor |
-F | Follow name (survives rotation) |
-q | Suppress filenames |
-v | Always show filenames |
When to Use Which
| Situation | Command |
|---|---|
| Small file, quick look | cat file |
| Large file, interactive read | less file |
| Large file, search needed | less file then /pattern |
| First lines of a file | head file |
| Last lines of a file | tail file |
| Watch a log | tail -F file |
| Extract line range | head -n X file | tail -n Y |
| Pipeline output | command | less or command | tail |
Comparison
| Aspect | cat | less | head | tail |
|---|---|---|---|---|
| Loads whole file | Yes | No | Partial | Partial |
| Interactive | No | Yes | No | No |
| Search | No | Yes | No | No |
| Follow growth | No | Yes (F) | No | Yes (-f) |
| Good for large files | No | Yes | Yes | Yes |
Headers with Multiple Files
| Command | Behavior |
|---|---|
head a.txt b.txt | Filename header per file |
head -q a.txt b.txt | No headers |
tail a.txt b.txt | Filename header per file |
tail -q a.txt b.txt | No headers |
Best Practices
โ Do This:
# Use less for anything you'll read
less /var/log/syslog # โ
# Use head to peek at unknown files
head suspicious.bin # โ
# Use tail -F for logs that rotate
tail -F /var/log/nginx/access.log # โ
# Pipe command output to less
ps aux | less # โ
# Use head + tail for line ranges
head -n 50 file | tail -n 10 # lines 41-50 # โ
# Search in less instead of cat | grep
less file # then /pattern # โ
โ Don’t Do This:
# Don't cat large files
cat huge.log # floods terminal, shows only end # โ ๏ธ
# Don't use more when less is available
more /etc/services # no backward scrolling # โ ๏ธ
# Don't use tail -f on rotating logs
tail -f /var/log/nginx/access.log # breaks on rotation # โ ๏ธ
# Don't cat | grep when less search works
cat file | grep error # less file then /error is better # โ ๏ธ
# Don't assume head/tail show the whole picture
head file # only first 10 lines # โ ๏ธ
Common Pitfalls
| Pitfall | Problem | Solution |
|---|---|---|
cat on huge file | Terminal floods, scrollback lost | Use less |
tail -f on rotating log | Stops following after rotation | Use tail -F |
Forgetting q in less | Stuck in pager | Press q |
less search case-sensitive | Misses matches | less -i or \c in pattern |
head/tail with no -n | Only 10 lines | -n N |
cat -A confused by ^M | Looks like garbage | It’s CRLF โ convert with dos2unix |
tail -n +0 | Error or unexpected | Start from 1: +1 |
Piping to less without -R | Colors lost | less -R |
Real-World Examples
1. View a config file
cat /etc/hostname
2. Page through a large log
less /var/log/syslog
3. Search in less
less /var/log/auth.log
# type: /failed
4. First lines of a script
head -n 5 deploy.sh
5. Last lines of a log
tail /var/log/kern.log
6. Follow a log live
tail -F /var/log/nginx/access.log
7. Skip a CSV header
tail -n +2 data.csv
8. Number lines for reference
cat -n script.sh | less
9. Show tabs and line endings
cat -A Makefile
10. Extract line range
sed -n '5,10p' file
# or
head -n 10 file | tail -n 6
11. Pipe process list to less
ps aux | less
12. Check binary file type
head -c 100 /bin/ls | file -
13. Monitor a growing output file
tail -f /tmp/build.log
14. Concatenate for a diff
cat old.txt new.txt > combined.txt
diff <(cat old.txt) <(cat new.txt)
15. View compressed file
zcat file.gz | less
# or
less file.gz # if lesspipe installed
16. Show last 100 lines of journal
journalctl -n 100
17. Watch log for a specific pattern
tail -f /var/log/syslog | grep --line-buffered "error"
18. Number non-blank lines only
cat -b code.py
19. Squeeze blank lines
cat -s file.txt
20. First and last lines of a file
head -n 1 file && tail -n 1 file
Visual: When Each Tool Shines
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ File size โ โ
โ โ
โ Small (1 screen) Large (many screens) โ
โ โ โ โ
โ โผ โผ โ
โ โโโโโโโโ โโโโโโโโโ โ
โ โ cat โ โ less โ โ
โ โโโโโโโโ โโโโโโโโโ โ
โ โ
โ Only beginning? Only end? โ
โ โ โ โ
โ โผ โผ โ
โ โโโโโโโโ โโโโโโโโ โ
โ โ head โ โ tail โ โ
โ โโโโโโโโ โโโโโโโโ โ
โ โ
โ File grows? โ
โ โ โ
โ โผ โ
โ โโโโโโโโโโโ โ
โ โ tail -F โ โ
โ โโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Visual: cat vs less on a Large File
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ cat large.log โ
โ โ
โ Line 1 โ
โ Line 2 โ
โ ... โ
โ Line 999,999 โ
โ Line 1,000,000 โ you see this โ
โ โ
โ (all previous lines scrolled past) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ less large.log โ
โ โ
โ Line 1 โ
โ Line 2 โ
โ ... โ
โ Line 24 โ screen fits 24 โ
โ โ
โ : (waiting for command) โ
โ โ
โ Press Space โ next screen โ
โ Press /foo โ search โ
โ Press q โ quit โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Visual: tail -f vs tail -F During Rotation
Without rotation (tail -f works):
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ app.log โ
โ line 1 โ
โ line 2 โ
โ line 3 โ tail -f shows this โ
โ line 4 โ and this โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
With rotation (tail -f breaks):
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ app.log โ renamed to app.log.1 โ
โ new app.log created โ
โ โ
โ tail -f still watches old fd โ
โ โ sees nothing new โ
โ โ
โ tail -F reopens by name โ
โ โ follows the new app.log โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Visual: head + tail for Line Range
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ file (100 lines) โ
โ โ
โ head -n 20 โ lines 1-20 โ
โ โ
โ tail -n 10 โ lines 91-100 โ
โ โ
โ head -n 20 file | tail -n 5 โ
โ โ โ
โ โผ โ
โ last 5 of first 20 โ
โ โ lines 16-20 โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Visual: Pipeline Composition
โโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโ
โ command โโโโโถโ filter โโโโโถโ viewer โ
โโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโ
โ โ โ
โผ โผ โผ
ps aux grep sshd less
seq 1 100 tail -n 5 cat
dmesg head -n 20 tail -f
Summary
| Command | Purpose | Best For |
|---|---|---|
cat | Concatenate/print | Small files, pipelines |
less | Page through | Large files, searching |
head | First lines | Peeking, headers |
tail | Last lines | Logs, newest entries |
tail -f | Follow descriptor | Watching non-rotating files |
tail -F | Follow name | Watching rotating logs |
Key takeaways:
catdumps and exits โ use it for small files and pipelines, not readinglessis the interactive viewer โ loads one screen, searches with/, quits withqheadshows the beginning โ first 10 lines by default,-nto changetailshows the end โ last 10 lines by default,-nto changetail -fstreams new lines โ for monitoring growing filestail -Fsurvives rotation โ follows the filename, not the descriptor- All four read stdin โ
command | less,command | tail head+tailextracts ranges โhead -n 20 file | tail -n 5gives lines 16-20lesssearch beatscat | grepโ interactive, highlights, navigablecat -Aexposes hidden characters โ CRLF, tabs, control codes- Use
lessfor anything you’ll read โ it’s faster thancaton large files
Remember: Viewing files is read-only, but the wrong command wastes time and floods terminals. cat is for concatenation and pipelines. less is for reading. head and tail are for slicing. tail -F is for logs. When in doubt about a file’s size, start with less โ it handles everything gracefully.
Stop using slow, ad-bloated tool sites! ๐คฎ
๐ Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
โ
Finance (Mortgage, Interest, Inflation)
โ
Tech (Base64, JSON, Dev Suite, IP)
โ
Health (BMI, BMR, TDEE)
โ
Productivity (Timer, Workspace, QR)
โก๏ธ Fast & Private
๐ No data leaves your device
๐ 100% Free
๐ Use it now: https://tools.kandz.me
๐ Bookmark itโyouโll need it later!