| |

LFCS 13 🐧 Viewing Files — cat, less, head, tail

A file has content. The content can be small—a configuration line, a hostname—or large—a log file with millions of entries, a kernel source tree. The tools for reading the content are the ones that differ by the size and the purpose. The cat is for the small files and the concatenation. The less is for the large files and the navigation. The head and the tail are for the beginning and the end, and the tail -f is for the live logs. The LFCS exam expects these tools to be automatic, and the exam tasks often require reading the configuration, the logs, and the output.

Key point: cat file prints the whole file to the standard output. less file opens the file in a pager with the navigation. head file prints the first 10 lines. tail file prints the last 10 lines. tail -f file follows the file as it grows, which is the tool for the live logs. cat is for the small files and the concatenation; less is for the large files; head and tail are for the specific parts.


Why the viewing tools matter

The size problem. A cat of a 10 GB log file floods the terminal and consumes the memory. The less reads the file incrementally and shows one screen at a time. The tool should match the size.

The navigation problem. The cat prints the whole file and returns to the prompt. There is no way to scroll back with the keyboard in most terminals, and the search is impossible. The less provides the scroll, the search, and the navigation. The less is the tool for the exploration.

The specific-part problem. The configuration is often at the top of the file, and the errors are often at the bottom. The head and the tail show the specific part without the whole file. The tail -f is the live view of the file as it grows.

The concatenation problem. The cat concatenates the multiple files into the standard output. The cat file1 file2 > combined combines the files. The cat is the tool for the combination, and the less is the tool for the reading.

The pipeline problem. The cat is used in the pipelines, though the cat file | command is often redundant with the command < file. The cat is for the cases where the file is the argument and the output is the pipe. The cat is the tool for the simple cases, and the dedicated tools are for the complex.


a. The cat command

The cat prints the file to the standard output.

$ cat file.txt

The whole content is printed. The command returns to the prompt. The output can be piped to another command.

$ cat file.txt | grep "error"

The cat prints the file, and the grep filters the lines. The same result with the grep "error" file.txt is shorter and avoids the extra process.

The multiple files are concatenated.

$ cat file1.txt file2.txt file3.txt

The three files are printed in order. The output is the concatenation.

The -n option numbers the lines.

$ cat -n file.txt
     1  first line
     2  second line
     3  third line

The -b option numbers the non-empty lines only.

$ cat -b file.txt
     1  first line

     2  second line

The -s option squeezes the multiple blank lines into one.

$ cat -s file.txt

The -A option shows the non-printing characters.

$ cat -A file.txt
line1$
line2$
line3$

The $ is the end of the line. The -A is the equivalent of the -vET. The option is for the files that may have the hidden characters, the carriage returns, or the tabs.

The -E option shows the $ at the end of each line. The -T option shows the tabs as ^I. The -v option shows the non-printing characters.

$ cat -E file.txt
line1$
line2$

The cat with the redirection creates the file.

$ cat > newfile.txt
This is the content.
Press Ctrl+D to end.

The cat reads the standard input and writes it to the file. The Ctrl+D is the end of the input.

The cat with the append.

$ cat >> newfile.txt
More content.

The >> appends the content to the file. The > overwrites.

The cat with the here-document.

$ cat << EOF > config.txt
line1
line2
EOF

The << is the here-document. The EOF is the delimiter. The lines between the cat and the EOF are the content. The pattern is for the scripted file creation.

The tac command is the cat reversed.

$ tac file.txt

The lines are printed in the reverse order. The tac is the tool for the log files where the last entry is the most recent.


b. The less command and the pager

The less opens the file in a pager.

$ less file.txt

The file is displayed one screen at a time. The navigation keys are the same as the man pages.

KeyAction
SpaceNext page
bPrevious page
jNext line
kPrevious line
GGo to end
gGo to beginning
/patternSearch forward
?patternSearch backward
nNext match
NPrevious match
qQuit

The less is the tool for the large files. The cat of the large file is the mistake.

The less with the -N option shows the line numbers.

$ less -N file.txt

The less with the -S option disables the line wrapping. The long lines are truncated, and the horizontal scroll is available with the arrow keys.

$ less -S file.txt

The less with the -F option quits automatically if the file fits on one screen.

$ less -F file.txt

The -F is useful in the scripts where the less should behave like the cat for the small files and the pager for the large.

The less with the + option opens at the specific line.

$ less +100 file.txt

The file opens at the line 100. The +G opens at the end. The +/pattern opens at the first match.

$ less +G file.txt
$ less +/error file.txt

The less is the more replacement. The more is the older pager with fewer features. The less is the standard.

The less with the input from the pipe.

$ command | less

The output of the command is paged. The pattern is for the long output that should not flood the terminal.

The less with the multiple files.

$ less file1.txt file2.txt

The files are opened in sequence. The :n goes to the next file, and the :p goes to the previous.


c. The head and tail commands

The head prints the first 10 lines.

$ head file.txt

The -n option specifies the number of lines.

$ head -n 20 file.txt
$ head -20 file.txt

The -c option specifies the number of bytes.

$ head -c 100 file.txt

The first 100 bytes are printed.

The tail prints the last 10 lines.

$ tail file.txt

The -n option specifies the number of lines.

$ tail -n 20 file.txt
$ tail -20 file.txt

The -c option specifies the number of bytes.

$ tail -c 100 file.txt

The -f option follows the file as it grows.

$ tail -f /var/log/syslog

The command prints the last 10 lines and then waits for the new lines. The new lines are printed as they are written. The Ctrl+C stops the follow.

The tail -f is the tool for the live logs. The tail -F is the same but retries if the file is rotated.

$ tail -F /var/log/syslog

The -F is the --follow=name --retry. The option handles the log rotation: when the file is renamed and the new file is created, the -F follows the new file. The -f follows the file descriptor, and the rotation breaks it.

The tail with the -n +N starts at the line N.

$ tail -n +2 file.txt

The output starts at the line 2 and continues to the end. The +2 is the “start at the line 2” syntax. The pattern is for the files with the header line that should be skipped.

The tail -f with the multiple files.

$ tail -f file1.log file2.log

The output is prefixed with the file names. The pattern is for the multiple logs that should be monitored together.

The head and the tail combined for the middle.

$ head -n 20 file.txt | tail -n 10

The first 20 lines are piped to the tail, which prints the last 10 of those. The result is the lines 11-20. The pattern is for the specific range without the sed.

The sed alternative.

$ sed -n '11,20p' file.txt

The sed prints the lines 11-20. The sed is the tool for the arbitrary range, and the head | tail is the combination for the simple case.

The tail with the -f and the grep.

$ tail -f /var/log/syslog | grep "error"

The live log is filtered for the “error” lines. The grep buffers the output, and the --line-buffered option makes it print the lines as they arrive.

$ tail -f /var/log/syslog | grep --line-buffered "error"

The --line-buffered is the option that makes the grep flush the output on each line. Without it, the output is buffered and the lines are printed in the blocks.


Complete Example Session

# ============================================
# PART 1: BASIC CAT
# ============================================
cat file.txt
# ============================================
# PART 2: CAT WITH NUMBERS
# ============================================
cat -n file.txt
cat -b file.txt
# ============================================
# PART 3: CAT WITH NON-PRINTING
# ============================================
cat -A file.txt
# ============================================
# PART 4: CAT TO CREATE
# ============================================
cat > newfile.txt
# Type the content, Ctrl+D to end
# ============================================
# PART 5: HERE-DOCUMENT
# ============================================
cat << EOF > config.txt
line1
line2
EOF
# ============================================
# PART 6: LESS
# ============================================
less file.txt
# Space, b, /pattern, n, q
# ============================================
# PART 7: LESS WITH OPTIONS
# ============================================
less -N file.txt
less +G file.txt
less +/error file.txt
# ============================================
# PART 8: HEAD
# ============================================
head file.txt
head -n 20 file.txt
head -c 100 file.txt
# ============================================
# PART 9: TAIL
# ============================================
tail file.txt
tail -n 20 file.txt
tail -n +2 file.txt
# ============================================
# PART 10: TAIL -F AND GREP
# ============================================
tail -f /var/log/syslog
tail -F /var/log/syslog
tail -f /var/log/syslog | grep --line-buffered "error"

The ten parts covered the basic cat, the numbers, the non-printing, the create, the here-document, the less, the less options, the head, the tail, and the tail -f with the grep.


Quick Reference

cat Options

OptionEffect
cat filePrint the file
cat -nNumber all lines
cat -bNumber non-empty
cat -sSqueeze blank lines
cat -AShow non-printing
cat -EShow $ at end
cat -TShow tabs as ^I

less Keys

KeyAction
SpaceNext page
bPrevious page
j/kNext/previous line
G/gEnd/beginning
/patternSearch forward
n/NNext/previous match
qQuit

head and tail

CommandEffect
head fileFirst 10 lines
head -n 20First 20 lines
head -c 100First 100 bytes
tail fileLast 10 lines
tail -n 20Last 20 lines
tail -n +2From the line 2
tail -f fileFollow
tail -F fileFollow with retry

Common Patterns

PatternPurpose
cat file1 file2 > combinedConcatenate
cat << EOF > fileHere-document
command | lessPage the output
tail -f log | grep patternLive filter
head -20 file | tail -10Lines 11-20
sed -n '11,20p' fileLines 11-20

Best Practices

āœ… Do This:

# Use less for the large files
less /var/log/syslog                                          # āœ…

# Use tail -f for the live logs
tail -f /var/log/syslog                                       # āœ…

# Use tail -F for the rotated logs
tail -F /var/log/syslog                                       # āœ…

# Use head for the first lines
head -n 20 file.txt                                           # āœ…

# Use the here-document for the scripted file creation
cat << EOF > config.txt
line1
EOF
                                                              # āœ…

# Use the line-buffered grep with the tail -f
tail -f log | grep --line-buffered "error"                    # āœ…

# Use the sed for the arbitrary range
sed -n '11,20p' file.txt                                      # āœ…

āŒ Don’t Do This:

# Don't cat the large files
cat /var/log/syslog  # floods the terminal                    # āŒ

# Don't forget the -F for the rotated logs
tail -f /var/log/syslog  # breaks on rotation                 # āš ļø

# Don't use the unquoted patterns
grep $pattern file  # word splitting                          # āš ļø

# Don't use the cat in the pipe when the command accepts the file
cat file | grep "x"  # use: grep "x" file                     # āš ļø

# Don't use the head | tail for the complex ranges
head -100 file | tail -50  # use: sed -n '51,100p'            # āš ļø

# Don't forget the line-buffered grep with the tail -f
tail -f log | grep "error"  # buffered, no output              # āš ļø

# Don't cat the binary files
cat /bin/ls  # garbage output                                 # āŒ

Common Pitfalls

PitfallWhy It HappensFix
Terminal floodedcat on the large fileUse less
Log rotation breaks follow-f follows the descriptorUse -F
Grep output bufferedNo --line-bufferedAdd the option
Binary garbagecat on the binaryUse less or xxd
Wrong rangehead | tail off-by-oneUse sed
Blank linescat -s missingAdd the option

Real-World Examples

1. Read a Config

cat /etc/hostname

2. View a Log

less /var/log/syslog

3. First Lines

head -n 20 /etc/passwd

4. Last Lines

tail -n 20 /var/log/syslog

5. Follow a Log

tail -f /var/log/syslog

6. Follow with Retry

tail -F /var/log/syslog

7. Live Filter

tail -f /var/log/syslog | grep --line-buffered "error"

8. Concatenate

cat part1.txt part2.txt > combined.txt

9. Here-document

cat << EOF > config.txt
server=localhost
port=8080
EOF

10. Skip the Header

tail -n +2 data.csv

Visual

Tool Selection

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│  SMALL FILE (< 1 screen)                                    │
│  cat file.txt                                               │
│                                                             │
│  LARGE FILE                                                 │
│  less file.txt                                              │
│                                                             │
│  FIRST LINES                                                │
│  head file.txt                                              │
│                                                             │
│  LAST LINES                                                 │
│  tail file.txt                                              │
│                                                             │
│  LIVE LOG                                                   │
│  tail -f file.txt                                           │
│                                                             │
│  The tool matches the size and the purpose.                 │
│                                                             │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

tail -f vs tail -F

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│  tail -f                                                    │
│                                                             │
│  Follows the file descriptor.                               │
│  Log rotation: the file is renamed, the new file is created.│
│  The -f keeps the old descriptor, and the new file is       │
│  ignored.                                                   │
│                                                             │
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
│                                                             │
│  tail -F                                                    │
│                                                             │
│  The --follow=name --retry.                                 │
│  Log rotation: the file is renamed, the new file is created.│
│  The -F detects the new file and follows it.                │
│                                                             │
│  The -F is the tool for the rotated logs.                   │
│                                                             │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

head and tail Ranges

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│  head -n 20 file.txt                                        │
│  → Lines 1-20                                               │
│                                                             │
│  tail -n 20 file.txt                                        │
│  → Lines N-19 to N                                          │
│                                                             │
│  tail -n +2 file.txt                                        │
│  → Lines 2 to N                                             │
│                                                             │
│  head -20 file.txt | tail -10                               │
│  → Lines 11-20                                              │
│                                                             │
│  sed -n '11,20p' file.txt                                   │
│  → Lines 11-20 (cleaner)                                    │
│                                                             │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

Live Log Filter

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│  tail -f /var/log/syslog | grep "error"                     │
│                                                             │
│  The tail writes the lines.                                 │
│  The grep buffers the output.                               │
│  The lines appear in the blocks, not the live.              │
│                                                             │
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
│                                                             │
│  tail -f /var/log/syslog | grep --line-buffered "error"     │
│                                                             │
│  The tail writes the lines.                                 │
│  The grep flushes on each line.                             │
│  The lines appear live.                                     │
│                                                             │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

Summary

ItemValue
catPrint the whole file
lessPager
headFirst 10 lines
tailLast 10 lines
tail -fFollow the file
tail -FFollow with retry
head -n NFirst N lines
tail -n NLast N lines
tail -n +NFrom the line N
cat -nNumber the lines
less +GOpen at the end
grep --line-bufferedLive filter

Key takeaways:

  • The cat is for the small files and the concatenation. The cat file1 file2 > combined combines the files. The cat on the large file floods the terminal.
  • The less is the pager. The navigation, the search, and the horizontal scroll. The less is the tool for the large files and the exploration.
  • The head and the tail show the specific part. The head for the beginning and the tail for the end. The tail -n +N starts at the line N. The head | tail combination is for the simple range, and the sed is for the clean range.
  • The tail -f follows the file, and the tail -F handles the rotation. The -f follows the file descriptor. The -F follows the file name and retries. The -F is the tool for the rotated logs.
  • The grep --line-buffered is the live filter. Without the option, the grep buffers the output, and the lines appear in the blocks. The --line-buffered flushes on each line.
  • The less is the man pager. The navigation keys are the same. The /pattern search, the n next, and the q quit. The less is the tool for the exploration.
  • The cat with the here-document is the scripted file creation. The cat << EOF > file creates the file with the content between the cat and the EOF. The pattern is for the scripts and the provisioning.

Remember: The tool matches the size and the purpose. The cat for the small files, the less for the large, the head and the tail for the specific parts. The tail -F for the rotated logs, and the grep --line-buffered for the live filter. The cat is the simple tool, and the less is the exploration. The LFCS tasks require the reading of the configuration, the logs, and the output, and the choice of the tool is the detail that makes the reading efficient.



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!