To view file contents in Linux without opening an editor, use cat filename to print the entire file to the screen, less filename to page through it interactively, head filename for the first 10 lines, or tail filename for the last 10 lines. Use tail -f filename to watch a growing file (like a log) in real time. These commands are faster than opening a text editor when you only need to read a file, not modify it.
Reading Without Editing
Not every interaction with a file requires editing it. Far more often, you simply want to see what a file contains — check a configuration setting, review the end of a log file, verify a script’s content before running it, or quickly scan a document. Opening a full text editor for these read-only tasks is unnecessary overhead: an editor loads the entire file into an editable buffer, presents a UI designed around modification, and requires an explicit exit sequence when you are done.
Linux provides an excellent set of dedicated viewing tools, each optimized for a specific viewing scenario. cat for short files you want to see in their entirety. less for long files you want to navigate and search. head and tail for looking at just the beginning or end. tail -f for watching a file grow in real time. Specialized viewers for compressed files, binary files, and structured data. Learning these tools transforms file inspection from a multi-step editor workflow into a single, fast command.
This article covers every practical file-viewing tool in the Linux toolkit, when to reach for each one, and the techniques that make file inspection efficient.
cat: Display the Entire File
cat (concatenate) is the simplest file viewer — it prints a file’s entire content to the terminal from beginning to end:
$ cat notes.txt
Meeting notes from Feb 18
- Discussed Q1 roadmap
- Action items assigned
- Next meeting: Feb 25
When cat Is the Right Choice
cat works well for short files that fit comfortably on screen — configuration files, small scripts, brief notes. For anything longer than a screen’s worth of content, the output scrolls past faster than you can read it, making less a better choice.
Viewing Multiple Files at Once
$ cat file1.txt file2.txt file3.txt
This concatenates and displays all three files in sequence — the origin of the command’s name.
cat with Line Numbers
$ cat -n script.sh
1 #!/bin/bash
2 echo "Starting process"
3 tar -czf backup.tar.gz /home/sarah/
4 echo "Backup complete"
Line numbers are especially useful when referencing specific lines — for example, when an error message points to “line 42” and you want to see what is there.
Showing Non-Printing Characters
$ cat -A file.txt # Show all non-printing characters
$ cat -T file.txt # Show tabs as ^I
$ cat -E file.txt # Show line endings as $
This helps diagnose invisible formatting issues — trailing whitespace, tab vs. space inconsistencies, or Windows-style line endings (\r\n) mixed into a Unix text file.
Numbering Only Non-Blank Lines
$ cat -b file.txt
less: Page Through Long Files Interactively
less is the standard tool for viewing files too long to fit on one screen. Unlike cat, which dumps everything at once, less displays one screen at a time and lets you navigate.
$ less biglogfile.txt
Navigation in less
| Key | Action |
|---|---|
Space or Page Down |
Next page |
b or Page Up |
Previous page |
↓ / j |
Scroll down one line |
↑ / k |
Scroll up one line |
g |
Go to the beginning of the file |
G |
Go to the end of the file |
/searchterm |
Search forward |
?searchterm |
Search backward |
n |
Next search match |
N |
Previous search match |
q |
Quit |
Why “less” Is More Than “more”
less is named as a pun on the older more command it was designed to replace — “less is more.” Unlike more, less allows backward scrolling, does not need to read the entire file before displaying it (making it fast even on huge files), and provides search functionality.
less with Line Numbers
$ less -N file.txt
Following a Growing File with less
$ less +F logfile.txt
This starts less in “follow mode” (similar to tail -f), showing new content as it is appended. Press Ctrl+C to stop following and return to normal less navigation, and Shift+F to resume following.
Viewing Command Output with less
Any command’s output can be piped into less for easier reading:
$ ps aux | less
$ dmesg | less
$ history | less
This is one of the most common uses of less — taming command output that would otherwise scroll past too quickly to read.
head: View the Beginning of a File
head shows the first lines of a file — the default is 10 lines:
$ head server.log
2026-02-18 08:00:01 Server started
2026-02-18 08:00:02 Listening on port 8080
2026-02-18 08:00:15 Client connected: 192.168.1.100
...
Specifying the Number of Lines
$ head -n 20 server.log # First 20 lines
$ head -20 server.log # Equivalent shorthand
$ head -n 1 server.log # Just the first line
Viewing the Beginning of Multiple Files
$ head file1.txt file2.txt
==> file1.txt <==
[content of file1]
==> file2.txt <==
[content of file2]
head automatically labels each file’s section when given multiple files.
head by Bytes Instead of Lines
$ head -c 100 file.txt # First 100 bytes
Useful for binary files or when you want a fixed-size preview regardless of line structure.
tail: View the End of a File
tail shows the last lines of a file — the default is also 10 lines:
$ tail server.log
2026-02-18 11:45:02 Request processed: /api/users
2026-02-18 11:45:03 Response sent: 200 OK
2026-02-18 11:45:10 Client disconnected: 192.168.1.100
Since logs and continuously-updated files grow by appending to the end, tail is the natural tool for checking recent activity.
Specifying the Number of Lines
$ tail -n 50 server.log # Last 50 lines
$ tail -50 server.log # Equivalent shorthand
tail -f: Following a File in Real Time
The most powerful and commonly used tail feature — continuously monitor a file as new content is appended:
$ tail -f server.log
This command does not exit; it keeps running, printing new lines as they are written to the file. Press Ctrl+C to stop. This is the standard way to watch a log file while a service is running, immediately seeing new entries as they occur.
Following multiple files simultaneously:
$ tail -f access.log error.log
==> access.log <==
[new lines from access.log as they appear]
==> error.log <==
[new lines from error.log as they appear]
Each file’s new content is labeled, letting you monitor several logs in a single terminal.
tail -F: Following Even If the File Is Rotated
$ tail -F server.log
Capital -F handles log rotation gracefully — if the log file is renamed or replaced (a common practice with logrotate), tail -F automatically detects the new file and continues following it, whereas lowercase -f would keep following the old, now-static file handle.
Combining head and tail
View a specific range of lines (for example, lines 50 through 60):
$ head -n 60 file.txt | tail -n 11
This gets the first 60 lines, then takes the last 11 of those — effectively lines 50 through 60.
watch: Repeatedly Viewing a Changing File or Command
While tail -f watches for appended content, watch re-runs an entire command repeatedly, useful for monitoring something that changes in place rather than just growing:
$ watch -n 2 cat /proc/loadavg # Refresh every 2 seconds
$ watch -n 5 'ls -la /var/spool/mail/' # Watch a directory for changes
watch clears the screen and redisplays the command’s full output at each interval — different from tail -f‘s append-only monitoring.
grep: Viewing Only Matching Lines
While primarily a search tool, grep is often the fastest way to “view” the specific parts of a file you actually care about, especially in large files:
$ grep "ERROR" application.log
2026-02-18 09:15:23 ERROR Failed to connect to database
2026-02-18 10:22:41 ERROR Timeout waiting for response
With context lines (showing surrounding lines for better understanding):
$ grep -A 3 "ERROR" application.log # 3 lines After each match
$ grep -B 3 "ERROR" application.log # 3 lines Before each match
$ grep -C 3 "ERROR" application.log # 3 lines of Context on both sides
Case-insensitive and line-numbered:
$ grep -in "error" application.log
Viewing Compressed Files Without Extracting
Special tools let you view the content of compressed files directly, without decompressing them to disk first — useful for old rotated logs stored as .gz.
$ zcat file.txt.gz # cat equivalent for gzip files
$ zless file.txt.gz # less equivalent for gzip files
$ zgrep "pattern" file.txt.gz # grep equivalent for gzip files
$ zdiff file1.gz file2.gz # diff equivalent for gzip files
$ bzcat file.txt.bz2 # Same idea for bzip2 files
$ xzcat file.txt.xz # Same idea for xz files
Practical example — searching across many rotated logs at once:
$ zgrep "OutOfMemory" /var/log/application.log.*.gz
Viewing Binary Files Safely
Attempting to cat a binary file (an executable, an image, a compiled program) often produces garbled terminal output or even strange terminal behavior, since binary data contains control characters that your terminal misinterprets.
file: Identify What You Are Looking At First
Before attempting to view an unfamiliar file, check its type:
$ file mystery_file
mystery_file: ELF 64-bit LSB executable, x86-64, dynamically linked
$ file document.pdf
document.pdf: PDF document, version 1.7
$ file image.png
image.png: PNG image data, 1920 x 1080, 8-bit/color RGB
xxd and hexdump: Viewing Binary Content Safely
For inspecting binary files without corrupting your terminal:
$ xxd file.bin | head -20
00000000: 7f45 4c46 0201 0100 0000 0000 0000 0000 .ELF............
00000010: 0300 3e00 0100 0000 a010 0000 0000 0000 ..>.............
$ hexdump -C file.bin | head -20
Both show the file’s raw bytes in hexadecimal alongside their printable ASCII representation — the standard technique for examining binary file structure.
strings: Extract Readable Text From Binary Files
$ strings /usr/bin/some_program | head -20
strings scans a binary file and prints only the sequences of printable characters it finds — useful for quickly checking what text (error messages, version strings, embedded URLs) a compiled program contains, without needing to understand the full binary format.
Viewing Structured Data Files
JSON Files
Raw JSON (especially minified, single-line JSON) is hard to read directly. Pretty-print it:
$ cat data.json | python3 -m json.tool
$ cat data.json | jq . # If jq is installed (recommended)
jq is a dedicated JSON processor that not only pretty-prints but allows querying and filtering JSON data:
$ cat data.json | jq '.users[0].name'
CSV Files
$ column -s, -t < data.csv | less -S
This formats comma-separated values into aligned columns for easier reading, with less -S preventing line-wrapping so wide tables stay readable.
XML Files
$ xmllint --format data.xml | less
xmllint (part of libxml2-utils) pretty-prints XML with proper indentation.
Comparing Files Instead of Just Viewing
Sometimes what you actually want is not to view a file’s absolute content, but to see what is different between two versions:
$ diff file1.txt file2.txt
$ diff -u file1.txt file2.txt # Unified format (used in patches)
$ diff -y file1.txt file2.txt # Side-by-side comparison
$ vimdiff file1.txt file2.txt # Interactive diff viewer using vim
$ colordiff file1.txt file2.txt # Colorized diff output (install: sudo apt install colordiff)
Counting and Summarizing Instead of Full Viewing
Sometimes the useful information about a file is a count or summary rather than its full content:
$ wc -l file.txt # Count lines
$ wc -w file.txt # Count words
$ wc -c file.txt # Count bytes
$ wc -m file.txt # Count characters (differs from bytes with multi-byte encoding)
$ awk 'END {print NR}' file.txt # Alternative line count method
Choosing the Right Viewing Tool
| Situation | Best Tool |
|---|---|
| Short file, want to see it all | cat |
| Long file, want to navigate | less |
| Just want the beginning | head |
| Just want the end | tail |
| Watching a log grow in real time | tail -f |
| Watching a rotated log grow | tail -F |
| Finding specific lines in a huge file | grep |
| Viewing a compressed file | zcat / zless / zgrep |
| Unfamiliar file, unsure of type | file first |
| Binary file inspection | xxd or hexdump |
| Extracting text from a binary | strings |
| Pretty-printing JSON | jq or python3 -m json.tool |
| Comparing two files | diff |
| Just need a count | wc |
| Command output too long to read | Pipe to less |
Practical Combinations
Check the Last 100 Lines of a Log, Then Keep Watching
$ tail -n 100 -f application.log
This shows the most recent 100 lines immediately (giving context) and then continues following new additions — the most common way to start monitoring an active log.
View a File While Highlighting a Search Term
$ less -p "ERROR" application.log
Opens the file in less, jumping directly to and highlighting the first occurrence of “ERROR.”
Preview the First Few Lines of Every File in a Directory
$ head -n 3 *.txt
==> file1.txt <==
[first 3 lines]
==> file2.txt <==
[first 3 lines]
Check How Many Errors Occurred Today
$ grep "$(date +%Y-%m-%d)" application.log | grep -c ERROR
View a Remote File Without Downloading It Fully
$ ssh user@server "tail -100 /var/log/application.log"
Runs tail on the remote server and streams just the result back — much faster than copying an entire large log file locally just to check its end.
Quick Reference: File Viewing Commands
| Task | Command |
|---|---|
| Display entire file | cat filename |
| Display with line numbers | cat -n filename |
| Page through interactively | less filename |
| First 10 lines | head filename |
| First N lines | head -n N filename |
| Last 10 lines | tail filename |
| Last N lines | tail -n N filename |
| Follow a growing file | tail -f filename |
| Follow, handling rotation | tail -F filename |
| Search within a file | grep "pattern" filename |
| View with context around matches | grep -C 3 "pattern" filename |
| View a gzip file | zcat filename.gz or zless filename.gz |
| Search inside a gzip file | zgrep "pattern" filename.gz |
| Identify file type | file filename |
| View binary content | xxd filename or hexdump -C filename |
| Extract text from binary | strings filename |
| Pretty-print JSON | cat filename.json | jq . |
| Compare two files | diff file1 file2 |
| Count lines/words/bytes | wc filename |
Conclusion: The Right Tool for Every Glance
Viewing file contents efficiently is one of the most frequent tasks in Linux command-line work, and having the right specialized tool for each situation saves significant time compared to reflexively opening a text editor for every read-only glance. cat for quick, short files. less for anything longer, with search and navigation. head and tail for the beginning and end. tail -f for real-time monitoring. grep when you know what you are looking for. And specialized tools for compressed, binary, and structured data.
These tools compose naturally with pipes and redirection, letting you combine viewing with filtering, counting, and comparing in whatever combination answers your specific question. Once these become reflexive, checking a file’s content becomes as fast as thinking of the question you want answered.




