The first two LPIC-1 modules covered command-line concepts and how you move around the filesystem and work with files and directories. The next step is the content of those files.
Showing, editing and comparing file contents is daily work for every Linux administrator. Log analysis, configuration changes and shell scripts all depend on it.
❗ Important note: As in the previous modules, this series does not replace an official exam-prep course for the LPIC-1 certification. It is a practice-oriented companion for self-study, so you can understand and apply the denser topics more reliably.
Why text processing sits at the centre of Linux
Linux follows the UNIX idea that everything is a file — and most of those files are text. Unlike Windows, where much configuration lives in a registry or in binary formats, Linux uses plain, human-readable text files.
That has several advantages:
- Configuration can be changed with simple text editors
- Problems are easier to diagnose and fix
- Automation is easier because text is simple to process
- Administrators can trace and document changes
That text-first approach makes text-processing tools a basic skill for anyone working on Linux.
LPIC-1 relevance
In the LPIC-1 syllabus, “viewing and editing files” is a large topic, especially in these objectives:
- 103.2: basic file operations such as viewing, editing and searching
- 103.3: basic file manipulation (process text streams, filter files)
- 103.5: create, monitor and kill processes (relevant for watching files)
- 103.7: search and extract data from files
Together those areas are about 25% of the marks on LPIC-1 exam 101.
What this module covers
The following sections cover:
- Viewing file contents with
cat,less,more,headandtail - Editing text with editors such as nano and vim
- Finding files with
find,locate,whichandwhereis - Comparing files with
diffandcmp
💡 Note: As usual, the module uses these markers:
- 💡 Tips for more efficient work
- ⚠️ Warnings and pitfalls that save you trouble
- 🔧 Practical examples you can follow on a system
- ❗ Typical mistakes and how to fix them
How to get the most from this module
Run the commands in your own Linux environment while you read. Create test text files, try the viewers and editors, and watch the results.
💡 Tip: For text editors, practice is not optional. Reading about vim commands is not the same as using them on a real file.
Linux text processing is daily admin work. Skill here raises your productivity more than almost any other command-line habit.
Viewing files
As a Linux administrator you will work with text files every day — configuration, logs, scripts. Being able to display and navigate that content efficiently is a basic skill. Linux gives you several tools, each with its own strengths.
The cat command — show a whole file
cat (from concatenate) is one of the most basic tools for showing file contents. It was built to join files, but it is mainly used to print a whole file to the screen:
cat /etc/hosts
# Output:
127.0.0.1 localhost
127.0.1.1 ubuntu-server
# The following lines are desirable for IPv6 capable hosts
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
When should you use cat?
cat is best for:
- Small text files that fit on one screen
- A quick look at a file
- Situations where you want the whole content at once
- Feeding the output into other commands
Useful cat options
| Option | Description | Practical use |
|---|---|---|
-n |
Number all lines | Refer to specific lines in configuration files |
-b |
Number non-empty lines only | Useful for source code that uses blank lines for structure |
-A |
Show all control characters | Find hidden characters that cause problems |
-T |
Show tabs as ^I |
Tell tabs from spaces in indentation |
-E |
Show $ at the end of each line |
Make line endings and trailing spaces visible |
-s |
Squeeze repeated blank lines | Clean up needless empty space |
🔧 Practical example for troubleshooting:
# Look for hidden control characters in a configuration file
cat -A /etc/apache2/sites-available/000-default.conf | grep "^M"
# See tab vs space indentation in Python scripts
cat -T script.py
def hello_world():^I
····print("Hello World") # four spaces here
Uses of cat beyond a simple dump
cat can do more than print a file:
Create or overwrite a file:
$ cat > new_file.txt
This is a test.
This is the second line.
^D # press Ctrl+D to end input
Join files:
$ cat file1.txt file2.txt > combined.txt
Append to an existing file:
cat update.txt >> logfile.txt
Show binary files (usually not useful):
cat /bin/ls | head
⚠️ Important warning: Be careful with
caton binary files or very large text files. You can stall the terminal or flood it with unreadable characters.
Typical beginner mistake:
Many newcomers use cat where a specialised tool is better:
# Inefficient (loads the whole file):
$ cat largefile.log | grep "Error"
# Better (reads the file once and filters directly):
$ grep "Error" largefile.log
Experienced Linux users joke about this as a Useless Use of Cat (UUOC).
Better readability with more — page by page
What is more and why is it better for longer files?
more is a pager that shows file contents one screen at a time — a clear improvement over cat for longer files:
more /var/log/syslog
The command shows one screen, then waits for input before it continues. You get time to read instead of watching the file scroll away.
Using more — navigation keys
| Key | Action | When to use it |
|---|---|---|
| Space | One page forward | Fast paging |
| Enter | One line forward | Line-by-line reading |
b |
One page back (not in every implementation) | Re-read something |
/term |
Search forward for term |
Jump to content |
n |
Next match | Walk search hits |
q |
Quit | Back to the shell |
h |
Help | Learn more keys |
🔧 Practical example:
$ more /etc/services
# Press Space to page
# Type /http and Enter to search for "http"
# Press q to leave
When to use more, and when not
Advantages of more:
- Easy to use, almost no learning curve
- Available on almost every UNIX system
- Fine for a fast sequential read
Disadvantages of more:
- Many implementations cannot scroll backwards
- Limited search
- Less flexible than newer pagers such as
less
💡 Historical note:
moreis one of the oldest UNIX pagers.lesswas added later as a more flexible successor. The name is a joke on “less is more” — andlessreally does more thanmore.
Advanced navigation with less
What makes less better than more?
less is an extended more with two-way navigation and many extra features. It was built to remove the limits of more:
less /var/log/syslog
Unlike more, less does not load the whole file into memory at once, which makes it efficient on very large files. The name is a joke on “less is more”, even though less has more features than more.
Navigation in less
less has a large set of keys that speed up reading:
| Key | Action | Practical use |
|---|---|---|
| Arrow keys ↑↓ | Line by line | Precise reading |
| Arrow keys ←→ | Horizontal scroll | Long lines |
| Space / Page Down | One page forward | Fast paging of large files |
b / Page Up |
One page back | Re-read |
g |
Jump to the start | Headers |
G |
Jump to the end | Newest log lines |
/term |
Search forward | Find information |
?term |
Search backward | Search already-seen content |
n |
Next match | Walk hits |
N |
Previous match | Walk hits backwards |
&pattern |
Show only lines matching pattern |
Interactive filter like grep |
m + letter |
Set a mark | Bookmark a place |
' + letter |
Jump to a mark | Return to a bookmark |
F |
Follow mode (like tail -f) |
Watch a growing file |
= |
File information | Position and size |
q |
Quit | Back to the shell |
🔧 Practical example: advanced less use:
less +G /var/log/auth.log # open the file and jump to the end
# Type ?Failed and Enter to search backwards for failed logins
# Press N several times to walk older errors
# Type &password and Enter to show only lines containing "password"
# Press q to leave that filter
# Press F to follow new lines
Command-line options for less
less also takes options at start:
less -N /etc/passwd # show line numbers
less +100 largefile.txt # start at line 100
less +/error logfile.txt # search for "error" immediately
less -S wide_table.csv # no wrap (horizontal scroll)
less -i logfile.txt # case-insensitive search
💡 LPIC-1 exam tip:
lessis the default pager for man pages. Learn the navigation keys. The exam can ask you to search and move efficiently in man pages.
Why less matters for administrators
For Linux administrators less is essential for several reasons:
Efficiency on large files:
- Unlike
catormore,lesscan open gigabyte log files
Live monitoring:
- Follow mode (
F) watches logs in real time
Search:
- Complex search and filter patterns help with diagnosis
No file change:
- Unlike editors,
lessnever modifies the file
Universality:
- Works for text, binary files and even directories
⚠️ Watch out: Powerful as it is,
lessis not a substitute forgrepon complex patterns or fortail -fwhen you need lasting log follow in scripts.
Show the first lines with head
What head offers and when to use it
head is built to show the start of a file. By default it prints the first 10 lines:
head /etc/services
# Network services, Internet style
#
# Note that it is presently the policy of IANA to assign a single well-known
# port number for both TCP and UDP; hence, officially ports have two entries
# even if the protocol doesn't support UDP operations.
#
# Updated from https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml .
#
# New ports will be added on request if they have been officially assigned
# by IANA and used in the real-world or are needed by a debian package.
head is especially useful when:
- You want a quick look at the start of a file
- You want to check structure or format
- You need headers or metadata at the top
- You want the first entries of a sorted list
Changing the line count
The main option is -n, which sets how many lines to show:
head -n 3 /etc/passwd
# Output:
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
A short form of the same option:
head -5 /etc/passwd # first 5 lines
🔧 Practical examples:
Check CSV headers:
head -1 data.csv
ID,Name,Email,Department,Salary
See the newest Git commits:
git log | head -20
Top processes by memory:
$ ps aux | sort -rn -k 4 | head -5 # the 5 most memory-hungry processes
Check several files at once:
$ head -n 2 /etc/passwd /etc/group /etc/hosts
==> /etc/passwd <==
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
==> /etc/group <==
root:x:0:
daemon:x:1:
==> /etc/hosts <==
127.0.0.1 localhost
127.0.1.1 ubuntu-server
💡 Advanced tip: With
-cyou can show the first n bytes instead of lines:
$ head -c 20 binary_file # first 20 bytes
Show the last lines with tail
The counterpart to head — why tail is indispensable
tail is the counterpart to head and shows the last 10 lines by default:
tail /var/log/syslog
May 14 11:45:23 server systemd[1]: Started Session 42 of user admin.
May 14 11:46:01 server CRON[25051]: (root) CMD (run-parts --report /etc/cron.hourly)
Where head shows the start, tail is specialised for the end.
That makes it essential for:
- The newest log entries
- Watching changes in growing files
- Checking the last records in data or configuration
- Debugging running processes in real time
Ways to use tail
As with head, -n sets the line count:
tail -n 5 /var/log/auth.log # last 5 lines
tail -5 /var/log/auth.log # short form
A useful variant starts from a given line:
tail -n +100 file.txt # all lines from line 100
That skips the start of a file, or combines with head to cut a middle section:
tail -n +100 file.txt | head -n 10 # lines 100-109
The powerful -f (follow) option for live monitoring
The most important tail option is -f (follow), which keeps printing new lines as they are appended:
tail -f /var/log/apache2/access.log
The command does not exit. It watches the file and prints new entries until you stop it with Ctrl+C.
🔧 Practical example for diagnosis:
# Terminal 1: watch Apache logs live
tail -f /var/log/apache2/error.log
# Terminal 2: generate a failing request
curl http://localhost/missing-page
In the first terminal you see the error from the second terminal immediately — useful for live diagnosis.
Advanced tail features
For more advanced work tail has further options:
-F — a more robust follow:
tail -F /var/log/syslog
Unlike -f, -F follows the filename rather than the file descriptor. tail keeps watching even if the file is rotated (renamed) and a new file with the original name is created — essential for logging systems.
Watch several files at once:
$ tail -f /var/log/syslog /var/log/auth.log /var/log/apache2/error.log
==> /var/log/syslog <==
[new syslog entries]
==> /var/log/auth.log <==
[new auth.log entries]
==> /var/log/apache2/error.log <==
[new error.log entries]
Useful when a problem spans several components.
Combine with grep for targeted watching:
tail -f /var/log/syslog | grep --color "error\|warning\|critical"
Shows only new lines containing those words and highlights them.
⚠️ Important warning: Stop unused
tail -fprocesses. Left running, they can hold file handles and interfere with log rotation.
Use cases and creative command combinations
The real skill is combining these basic commands into solutions for daily admin work.
Extract lines from the middle of a file
# lines 50-60 of a file
head -60 /etc/services | tail -11
# alternative with sed
sed -n '50,60p' /etc/services
Live monitoring with several filters
# watch Apache hits from a given subnet, skip static files
tail -f /var/log/apache2/access.log | grep '192\.168\.1\.' | grep -v 'GET /static/'
Rotation-safe watching of important processes
# all sudo commands in real time
tail -F /var/log/auth.log | grep --color "sudo:"
# SSH logins and failures in real time
tail -F /var/log/auth.log | grep --color "sshd.*\(Failed\|Accepted\)"
Split large files into manageable chunks
# split a large CSV into files of 1000 lines each
split -l 1000 large_dataset.csv chunk_
# check the first chunk
head chunk_aa
Compare header and trailer
# compare head and tail of a file
diff <(head datafile.txt) <(tail datafile.txt)
❗ Typical mistake on large files:
# INEFFICIENT: loads the whole file for nothing
cat huge.log | grep "ERROR" | wc -l
# BETTER: only matching lines are processed
grep "ERROR" huge.log | wc -l
UNIX philosophy in action
These commands show the UNIX idea: write programs that do one thing well. Each command has a specific job; pipelines combine them into stronger behaviour.
💡 LPIC-1 exam tip: The exam often asks you to combine text-viewing commands to extract given information.
Know each command on its own, and practise combinations. The viewers look simple; using them well is what separates beginners from experienced administrators.
Editing text with editors
As a Linux administrator you spend a large share of the job editing text files — configuration, scripts, log analysis. Fluency in at least one capable text editor is a basic skill and a core LPIC-1 topic.
Text editor concepts on Linux
Why text editors sit at the centre of Linux administration
Linux configures and manages almost everything through text files. Windows often uses a binary registry or specialised GUIs. Linux uses plain text. That has real advantages:
Transparency:
- Plain text makes the configuration readable
Version control:
- Configuration changes are easy to track with Git or similar tools
Automation:
- Text files are easy to generate or change from scripts
- Portability: text files move between systems without fuss
Troubleshooting:
- Problems can be analysed in the clear text
🔧 Practical example from operations:
A server’s network address has to change.
Edit a single text file:
/etc/network/interfacesor/etc/sysconfig/network-scripts/ifcfg-eth0- Make the change in readable form
- Restart the network service
On Windows that is typically a sequence of clicks in several GUI dialogs.
The two main categories of Linux text editors
Terminal editors:
- Run on the command line with no graphical session
- Essential for servers without a GUI
- Light on resources and universally available
Examples:
nano,vim,emacs,joe
Graphical editors:
- Need a GUI (X11, Wayland)
- More familiar for people coming from Windows/Mac
- Often extra features for developers
Examples:
gedit,kate,Visual Studio Code,Sublime Text
⚠️ Important for LPIC-1: The certification is aimed at basic server and system administration, so the focus is on terminal editors, especially nano and vim. In production you often have only SSH and no GUI.
Criteria for choosing the right editor
Several factors matter:
| Criterion | Description | Practical meaning |
|---|---|---|
| Availability | Is the editor installed by default? | Critical in emergencies or on minimal systems |
| Learning curve | How fast can you become productive? | Initial time cost for new administrators |
| Efficiency | How fast are repeated tasks? | Daily productivity |
| Editing power | Support for complex work such as regular expressions | Demanding edits |
| Resource use | CPU and RAM | Older or constrained systems |
| Customisation | Can you adapt it to your habits? | Long-term productivity |
💡 Tip for beginners: Start with nano — it is friendly, shows help on screen, and is installed on most distributions. Once you are comfortable on Linux, invest time in vim; its efficiency is unmatched in the long run.
For LPIC-1 and for system administration you should know two editors in particular:
- nano: friendly for fast, simple edits
- vim: powerful and efficient, with a steeper learning curve
The beginner editor nano
What is nano and why is it a good starting point?
nano is a friendly terminal editor built to lower the barrier to Linux text editing. It is a free reimplementation of the older pico editor, originally part of the Pine email client.
Main advantages of nano for beginners:
- Intuitive use: shortcuts are shown at the bottom of the screen
- No modes: unlike vim, nano has no separate editing modes
- Productive immediately: new users can edit text without a briefing
- Widely available: installed by default on almost all modern distributions
How you start it:
nano file.txt # open or create file.txt
nano +25 file.txt # open file.txt and put the cursor on line 25
nano +/searchterm file.txt # open file.txt and search for "searchterm"
After opening you see an interface like this:
# GNU nano 6.2 file.txt
This is sample text in the file.
You can type here directly.
^G Help ^O Write Out ^W Where Is ^K Cut ^J Justify
^X Exit ^R Read File ^\ Replace ^U Paste ^T Spell
The ^ commands at the bottom are the main shortcuts. ^ means the Ctrl key.
Basic navigation and editing in nano
Typing in nano works like most familiar editors — you type and the text appears at the cursor.
Basic navigation:
| Shortcut | Action | Practical use |
|---|---|---|
| Arrow keys | Move the cursor | Basic movement |
| Ctrl+A | Start of line | Fast start of a line edit |
| Ctrl+E | End of line | Append at the end of a line |
| Ctrl+Y | One screen up | Page back in longer files |
| Ctrl+V | One screen down | Page forward |
| Alt+/ | End of file | Jump to the last line |
| Alt+\ | Start of file | Jump to the first line |
| Ctrl+_ | Go to a line number | Precise jumps in known files |
| Ctrl+C | Show cursor position | Orientation in large files |
Edit and manipulate text:
| Shortcut | Action | Practical use |
|---|---|---|
| Backspace/Delete | Delete characters | Standard deletion |
| Ctrl+K | Cut current line | Fast remove or move of lines |
| Ctrl+U | Paste cut text | Restore or move text |
| Alt+6 | Mark text | Start a selection (extend with arrows) |
| Alt+A | Set/unset mark | Alternative selection |
| Ctrl+6 | Copy instead of cut | Copy marked text without deleting |
| Ctrl+D | Delete the character under the cursor | Precise single-character delete |
| Ctrl+J | Justify paragraph | Even line breaks |
| Alt+D | Delete word | Faster word deletes |
🔧 Practical example — edit a configuration file:
$ sudo nano /etc/ssh/sshd_config
# In the editor:
# 1. Press Ctrl+W and type "PermitRootLogin" to find the line
# 2. Edit the line with arrows and Backspace/Enter
# 3. Change it to "PermitRootLogin yes"
# 4. Save with Ctrl+O and Enter
# 5. Leave with Ctrl+X
❗ Typical beginner mistake: After editing a system configuration file you must restart the matching service or the change has no effect:
sudo nano /etc/ssh/sshd_config # edit SSH configuration
sudo systemctl restart sshd # restart the SSH service
Saving and opening files
The most basic operations are saving changes and opening files:
| Shortcut | Action | Practical use |
|---|---|---|
Ctrl+O |
Save (“WriteOut”) | Keep changes without leaving |
Ctrl+X, then Y, Enter |
Exit and save | Fast save and quit |
On Ctrl+O you are asked for the filename. The current name is pre-filled:
File Name to Write: file.txt
Press Enter to save under the same name, or type a new name to make a copy.
⚠️ When editing system files: If you open a file without enough rights, nano shows
[ Read Only ]in the title. Saving then fails with “Permission denied”.
In that case:
# Wrong (insufficient rights):
nano /etc/ssh/sshd_config
# Right (with administrator rights):
sudo nano /etc/ssh/sshd_config
Open and insert files:
| Shortcut | Action | Practical use |
|---|---|---|
Ctrl+R |
Read a file into the current buffer | Insert another file’s content |
Alt+< |
Previous buffer | Switch among open files |
Alt+> |
Next buffer | Switch among open files |
🔧 Practical example — merge several configurations:
# Open a new file
nano merge.conf
# In the editor:
# 1. Write an introductory comment
# 2. Press Ctrl+R
# 3. Type "/etc/app1/config" and confirm with Enter
# 4. Add more comments
# 5. Press Ctrl+R again and insert "/etc/app2/config"
💡 Practice tip: Always take a backup before you edit a critical configuration file:
sudo cp /etc/fstab /etc/fstab.backup
sudo nano /etc/fstab
If something goes wrong, restore the backup.
Keyboard shortcuts for efficient work
Beyond the basics, nano has shortcuts that raise productivity:
| Shortcut | Action | Practical use |
|---|---|---|
| Ctrl+W | Search | Find configuration entries |
| Alt+W | Search again | Next match |
| Ctrl+\\ | Search and replace | Change values globally |
🔧 Example of efficient search and replace:
Change all IPv4 addresses from 192.168.1.x to 10.0.0.x:
- Press
Ctrl+\ - Search for:
192\.168\.1\. - Replace with:
10.0.0. - Choose
Afor “replace all” or confirm each change
Text formatting and manipulation
| Shortcut | Action | Practical use |
|---|---|---|
| Ctrl+J | Justify text | Format paragraphs |
| Alt+J | Justify paragraph | Format only the current paragraph |
| Alt+B | Find text in brackets | Navigate code |
| Alt+] | Jump to matching bracket | Check nested structures |
| Alt+# | Toggle line numbers | Navigation in large files |
| Alt+T | Indent with spaces instead of tabs | Keep formatting consistent |
Advanced features:
| Shortcut | Action | Practical use |
|---|---|---|
| Alt+R | Spell check (if installed) | Catch typos |
| Alt+D | Show line and character counts | Document statistics |
| Alt+P | Show whitespace (tabs/spaces) | Spot formatting errors |
| Alt+N | Toggle line numbers | Navigation in scripts |
⚠️ Note: Not every Alt combination works in every terminal emulator. In SSH sessions or some GUI terminals the system can swallow Alt keys.
💡 Exam-prep tip: For LPIC-1 you should know the basic nano shortcuts by heart, especially:
| Shortcut | Action | Use |
|---|---|---|
| Ctrl+O | Save | Keep file contents |
| Ctrl+X | Exit | Close the editor |
| Ctrl+W | Search | Find keywords |
| Ctrl+U | Paste | Restore cut text |
| Ctrl+K | Cut | Remove whole lines |
| Alt+T | Spaces instead of tabs | Consistent formatting |
The powerful vim
What is vim and why is the steep learning curve worth it?
vim (Vi IMproved) is a powerful, highly efficient text editor and a successor of the classic Unix editor vi. Nano is built for beginners; vim is aimed at advanced users and professionals. Time spent learning vim pays off for years.
Convincing advantages of vim:
Extreme efficiency:
- With practice you can edit text 3–5× faster than in other editors
Universal availability:
- Present on almost every Unix/Linux system (often as
/usr/bin/vi)
Minimal resources:
- Works in minimal environments and over slow links
Powerful text manipulation:
- Complex edits with a few keystrokes
Customisation and plugins:
- Thousands of plugins and unlimited configuration
vim /etc/hosts # start vim and open a file
vi /etc/hosts # on many systems vi is a link or alias to vim
vim +23 file.txt # open file.txt on line 23
vim +/ERROR logfile.log # open the log and search for "ERROR"
Understanding the modes — the key to vim
The core idea that sets vim apart is modes. That unusual approach is exactly what makes vim powerful:
Normal mode (also called command mode):
- The default when vim starts
- Keystrokes are commands, not text
- Optimised for navigation and complex edits
- A few keys do a lot of work
Insert mode:
- For typing text directly
- Entered with
i,a,oor other insert commands - Behaves like a conventional editor
- Leave with Esc back to Normal mode
Visual mode:
- For selecting and editing blocks
- Entered with
v(character),V(line) or Ctrl+v (block) - Precise operations on a selection
Command-line mode:
- For complex commands, search/replace, file operations
- Entered with
:from Normal mode - Access to hundreds of extra functions
- Leave by running a command or with Esc
┌─────────────────────────────────────────────────────────────┐
│ VIM MODE ARCHITECTURE │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────┐ i, a, o ┌───────────┐ │
│ │ ├────────────────────>│ │ │
│ │ Normal mode │ │ Insert │ │
│ │ (command) │<────────────────────┤ mode │ │
│ │ │ Esc │ (Insert) │ │
│ └──┬────────────▲─┘ └───────────┘ │
│ │ │ │
│ : │ │ Enter / Esc │
│ ▼ │ │
│ ┌───────────────┴─┐ v, V, Ctrl+v ┌───────────┐ │
│ │ Command-line ├────────────────────>│ Visual │ │
│ │ mode (:) │<────────────────────┤ mode │ │
│ │ │ Esc │ (Visual) │ │
│ └─────────────────┘ └───────────┘ │
└─────────────────────────────────────────────────────────────┘
⚠️ The most common vim confusion: Most frustration comes from typing text without entering Insert mode. If strange things happen or vim “goes mad” while you type, you are still in Normal mode.
🔧 Practical example — first steps with vim:
┌─────────────────────────────────────────────────────────────┐
│ VIM BASIC WORKFLOW │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1 Start: vim file.txt (open/create file) │
│ │ │
│ ▼ │
│ 2 Insert mode: press [i] ────► 3 type text │
│ │ │
│ ▼ │
│ 4 Normal mode: press [Esc] ──► 5 :w (save) │
│ │ │
│ ▼ │
│ 6 :q (quit) │
│ │
└─────────────────────────────────────────────────────────────┘
💡 Short form:
vim file.txt→i→ type text →Esc→:w→:q
| Combination | Action |
|---|---|
vim file.txt |
Open or create a file |
i |
Enter Insert mode |
| Type text | Edit the file |
Esc |
Return to Normal mode |
:w + Enter |
Save |
:q + Enter |
Quit vim |
💡 Tip:
:wqsaves and quits in one step.
Basic navigation and editing in vim
A main advantage of vim is efficient movement without leaving the home row.
| Key | Action | Practical use |
|---|---|---|
| h, j, k, l | Left, down, up, right | Movement without arrow keys |
| w | One word forward | Fast movement through text |
| b | One word back | Back to the start of a word |
| e | End of the current word | Precise placement |
| 0 | Start of line | Jump to the beginning of the line |
| $ | End of line | Jump to the end of the line |
| gg | Start of the document | First line |
| G | End of the document | Last line |
| 42G | Jump to line 42 | Go to a known line |
| Ctrl+F | One page forward | Fast paging |
| Ctrl+B | One page back | Fast paging back |
| H | Top of the screen | Visible start |
| M | Middle of the screen | Centre the work area |
| L | Bottom of the screen | Visible end |
💡 Efficiency tip: Many vim commands take a count:
| Combination | Action |
|---|---|
5j |
5 lines down |
3w |
3 words forward |
10x |
delete 10 characters |
Entering Insert mode:
| Key | Action | Practical use |
|---|---|---|
| i | Insert before the cursor | Standard insert |
| a | Insert after the cursor | Type after the current character |
| I | Insert at the start of the line | After leading whitespace |
| A | Insert at the end of the line | Append |
| o | New line below | Add lines quickly |
| O | New line above | Insert above |
| s | Delete character and insert | Replace a character |
| S | Delete line and insert | Replace a whole line |
| cc | Delete line and insert | Alternative to S |
| C | Delete from cursor to end of line and insert | Replace the rest of the line |
🔧 Practical example — edit a configuration line:
Change ListenPort 443 to ListenPort 8443:
| Combination | Action |
|---|---|
/ListenPort |
Search for “ListenPort” |
f4 |
Move the cursor to the character 4 |
s |
Delete that character and enter Insert mode |
8443 |
Type the new value |
Esc |
Back to Normal mode |
Editing in Normal mode:
| Command | Action | Practical use |
|---|---|---|
| x | Delete the character under the cursor | Single characters |
| X | Delete the character before the cursor | Backward delete without changing mode |
| dd | Delete the current line | Remove whole lines |
| yy | Yank (copy) the current line | Prepare a paste |
| p | Put after the cursor | Paste |
| P | Put before the cursor | Alternative paste position |
| u | Undo | Fix a mistake |
| Ctrl+r | Redo | Undo an undo |
| r | Replace one character | Fast single-letter change |
| . | Repeat the last command | Powerful for repeated edits |
| >> | Indent the line | Format code or lists |
| << | Reduce indent | Adjust formatting |
The real strength of vim: operators plus motions
In vim you combine operators (what to do) with motions (what to apply it to). The grammar is: [count][operator][motion]
| Combination | Action | Example |
|---|---|---|
| d3w | Delete 3 words | Remove several words |
| y$ | Yank to end of line | Part of a line to the clipboard |
| >} | Indent the next paragraph | Format a code block |
| c2j | Change this line and the next | Replace several lines |
| dt) | Delete until the next ) |
Remove text inside brackets |
| yi" | Yank text inside quotes | Fast copy of a string |
These combinations do precise edits that would take several actions in other editors.
❗ Typical vim beginner mistake: Forgetting to return to Normal mode before running commands. If your commands appear as text, press Esc.
Search and replace
vim search is strong and supports regular expressions.
Basic search:
| Command | Action | Practical use |
|---|---|---|
| /pattern | Search forward | Find text |
| ?pattern | Search backward | Search already-seen text |
| n | Next match (same direction) | Walk hits |
| N | Previous match | Walk hits backwards |
| \* | Search the word under the cursor (forward) | All occurrences of a word |
| # | Search the word under the cursor (backward) | Same, opposite direction |
| :set hlsearch | Highlight matches | Mark every hit |
| :noh | Turn highlighting off | Clear marks |
Advanced search and replace:
In command-line mode vim has powerful substitute commands:
| Command | Action | Example |
|---|---|---|
| :%s/old/new/g | Replace “old” with “new” in the whole file | :%s/http:/https:/g |
| :5,20s/old/new/g | Replace only on lines 5–20 | :5,20s/error/warning/g |
| :%s/old/new/gc | Confirm each replacement | :%s/color/colour/gc |
| :%s/old/new/gi | Case-insensitive search | :%s/User/user/gi |
The pattern is:
:[range]s/search/replacement/[flags]
| Element | Meaning |
|---|---|
| : | Start a command-line command |
| Range: % | Whole file |
| Range: 5,20 | Lines 5 to 20 |
| s | Substitute |
| Search | Text or regular expression |
| Replacement | Replacement text |
| Flag: g | Global (all matches on a line) |
| Flag: c | Confirm each replacement |
| Flag: i | Ignore case |
🔧 Practical example — change IP addresses in a configuration file:
:%s/192\.168\.1\.\([0-9]\+\)/10.0.0.\1/gc
This finds addresses in the form 192.168.1.x and replaces them with 10.0.0.x, keeping the last octet. The pattern uses a capture group that \1 reuses.
⚠️ Regular expressions in vim: Special characters such as
.,*,[,]must be escaped with a backslash if you mean them literally.
Save, quit and abort
Every vim user must be able to save and leave cleanly:
| Command | Action | Practical use |
|---|---|---|
| :w | Write (save) | Keep changes, stay in the editor |
| :q | Quit | Leave if there are no unsaved changes |
| :wq or :x | Save and quit | Normal finish |
| :q! | Quit without saving | Discard changes |
| :w filename | Save under a new name | Copy or rename |
| :w! | Force write | Read-only files (when allowed) |
| ZZ | Save and quit | Shortcut for :wq |
| ZQ | Quit without saving | Shortcut for :q! |
| :sav filename | Save as a new name and switch to that file | Branch a copy |
❗ Classic beginner situation — “I cannot leave vim!”:
- Press
Esc(to make sure you are in Normal mode) - Type
:q!and pressEnter - If that fails, try
:qor:wq
This is common enough to be a meme. With practice, entering and leaving vim becomes automatic.
💡 Rescue tip: If you opened a file in vim without write permission, you can still save with:
:w !sudo tee %
That writes the file with root rights even if you started vim without sudo.
The most important vim commands for LPIC-1
For LPIC-1 you should know these vim basics:
Essential operations:
| Command | Action |
|---|---|
vim filename |
Start vim |
i |
Enter Insert mode |
Esc |
Return to Normal mode |
Navigation:
- Basic movement:
h, j, k, lor arrow keys - By word:
w(forward),b(back) - Start/end of line:
0and$ - Start/end of document:
ggandG - Jump to a line:
:42
Editing:
- Delete a character:
x - Delete a line:
dd - Yank a line:
yy - Put:
p - Undo:
u - Redo:
Ctrl+r
Search:
- Forward:
/term - Next match:
n - Previous match:
N
Search and replace:
- Whole file:
:%s/old/new/g - With confirmation:
:%s/old/new/gc
🔧 Typical LPIC-1 exam scenario:
Edit the SSH configuration so the SSH port changes from 22 to 2222.
Solution:
| Command | Action |
|---|---|
sudo vim /etc/ssh/sshd_config |
Open the SSH configuration |
/Port |
Find the Port line |
i |
Enter Insert mode |
change 22 to 2222 |
Edit the port |
Esc |
Return to Normal mode |
:wq |
Save and quit |
sudo systemctl reload sshd |
Reload SSH (required) |
Editor configuration files
System-wide vs. user-specific configuration
Both nano and vim can be tuned with configuration files at system and user level, which matters for administrators.
Configuration files for nano:
| Path | Type | Use |
|---|---|---|
/etc/nanorc |
System-wide | Settings for every user |
~/.nanorc |
User-specific | Personal settings, override system-wide |
Configuration files for vim:
| Path | Type | Use |
|---|---|---|
/etc/vim/vimrc |
System-wide | Basic settings for every user |
/etc/vim/vimrc.local |
System-wide | Extra local tweaks (on some systems) |
~/.vimrc |
User-specific | Personal settings on top of the system file |
⚠️ Important for administrators: Changes to system-wide editor configs affect every user. Package updates can overwrite them.
Useful configuration options for administrators
Useful nano settings:
# In /etc/nanorc or ~/.nanorc
# Auto-indent (important for scripts and configuration)
set autoindent
# Show line numbers (navigation and troubleshooting)
set linenumbers
# Backup files with a ~ suffix
set backup
# Mouse support
set mouse
# Tab size of 4
set tabsize 4
# Soft-wrap long lines
set softwrap
# Syntax highlighting and colour definitions
include "/usr/share/nano/*.nanorc"
# Permanent status line at the bottom
set constantshow
# Always save in DOS/Windows format (cross-platform files)
# set dos
# Treat search and replace as regular expressions
# set regexp
These settings make nano a stronger daily admin tool:
🔧 Practical example
An administrator-friendly nano configuration:
cat > ~/.nanorc << EOF
set autoindent
set linenumbers
set constantshow
set tabsize 4
set mouse
include "/usr/share/nano/*.nanorc"
EOF
Useful vim settings:
# In /etc/vim/vimrc or ~/.vimrc
" Show line numbers
set number
" Syntax highlighting
syntax on
" Highlight search matches
set hlsearch
" Ignore case when searching
set ignorecase
set smartcase " respect case if the pattern has uppercase letters
" Auto-indent
set autoindent
" Indent of 4 spaces
set tabstop=4
set shiftwidth=4
set expandtab " tabs as spaces
" Always show the status line
set laststatus=2
" Remember the last position in the file
if has("autocmd")
au BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g'\"" | endif
endif
" Central backup directories instead of ~ files in the working directory
set backupdir=~/.vim/backup//
set directory=~/.vim/swap//
set undodir=~/.vim/undo//
In vim, comments start with " rather than #.
💡 Important for administrators: Storing backup, swap and undo files centrally stops vim leaving hidden files in the directories you edit — especially important for system files.
🔧 Practical example
Set up an administrator-friendly vim environment:
# Create the required directories
mkdir -p ~/.vim/{backup,swap,undo}
# Basic .vimrc
cat > ~/.vimrc << EOF
syntax on
set number
set hlsearch
set ignorecase
set smartcase
set autoindent
set tabstop=4
set shiftwidth=4
set expandtab
set laststatus=2
set backupdir=~/.vim/backup//
set directory=~/.vim/swap//
set undodir=~/.vim/undo//
EOF
System-wide configuration for a consistent admin environment
As a system administrator you often want the same editor environment on every machine. Adjust the system-wide files:
For nano:
sudo nano /etc/nanorc
# Add the settings you want
For vim:
sudo vim /etc/vim/vimrc.local
# On Debian/Ubuntu this file is sourced after /etc/vim/vimrc
⚠️ Important: System upgrades can overwrite system-wide configuration files.
To avoid that:
- Create separate files that the main configs include
- Document changes in a README in the same directory
- Use configuration management such as Ansible, Puppet or Chef
💡 LPIC-1 exam tip: Know where the editor configuration files live and how system and user settings interact. That hierarchy shows up in several LPIC-1 topics.
Other available editors at a glance
Nano and vim are the important editors for LPIC-1, but a Linux administrator should know other terminal editors:
| Editor | Description | Use case |
|---|---|---|
emacs |
Extremely powerful editor with its own Lisp | Complex programming and text work |
joe |
Simple editor with WordStar keys | Alternative for users of older systems |
mcedit |
Part of Midnight Commander | Friendly alternative with menus |
ed |
Original UNIX line editor | Scripts and very constrained environments |
micro |
Modern, intuitive editor | Beginner-friendly alternative to nano |
🔧 Practical example
Choosing an editor through environment variables:
# System default editor
sudo update-alternatives --config editor
# Personal editor via environment variables
echo 'export EDITOR=vim' >> ~/.bashrc
echo 'export VISUAL=vim' >> ~/.bashrc
These settings decide which editor opens when a program needs one (for example crontab -e or git commit).
Which editor for which job?
The right editor depends on the situation:
| Scenario | Recommended editor | Why |
|---|---|---|
| Fast, simple changes | nano |
Low barrier, productive immediately |
| Heavy text editing | vim |
High efficiency after the learning phase |
| Remote admin over slow links | vim |
Minimal bandwidth |
| Minimal systems (recovery) | vi/vim |
Universally available |
| Complex application development | vim or emacs |
Rich developer features |
| Linux newcomers | nano |
Intuitive, help on screen |
When you weigh the choice, consider:
Availability:
vi/vimis almost everywhere; other editors may need installing
Learning cost:
nanois learned in minutes;vimtakes days to weeks for the basics, months for mastery
Long-term productivity:
- The investment in
vimpays back in speed
Team standards:
- Admin teams often standardise on one editor for shared knowledge
💡 Career tip: Even if you start with nano, learn vim. Most experienced Linux administrators use vim or emacs, and many Linux job interviews include questions about advanced editors.
⚠️ For LPIC-1: Although nano is easier, you should know both editors for the exam. Tasks can require a specific editor.
Fluency in at least one terminal editor is required for every Linux administrator. Start with nano for quick wins, and invest in vim or another advanced editor for long-term efficiency.
Finding files
A Linux system can hold hundreds of thousands or millions of files. As an administrator you must find given files quickly — for maintenance, troubleshooting or changes. Linux offers several strong search commands, each with its own strengths.
The filesystem search engine
find is the most powerful and flexible file-search tool on Linux. Unlike other search commands, find walks the live filesystem and offers almost unlimited filters.
Basic find syntax
The basic pattern is:
find [start-directory] [options] [criteria] [action]
A simple example:
find /home/username -name "*.txt"
This searches /home/username and all subdirectories for names ending in .txt.
🔧 Practical example with an explanation:
find /etc -type f -name "*.conf" -size +10k
That command means:
- Search
/etcand all subdirectories - Regular files only (
-type f), not directories - Name must end in
.conf - Size must be greater than 10 kilobytes
Search by name
Name search is the most common use of find:
# Exact name
find /var/log -name "syslog"
# Wildcards
find /home -name "*.jpg"
# Ignore case
find /var/www -iname "index.*"
⚠️ Important: Quote wildcards used with
find, so the shell does not expand them beforefindsees them.
❗ Typical mistake:
find /home -name *.jpg # WRONG: the shell expands *.jpg first
find /home -name "*.jpg" # RIGHT: find processes the pattern
💡 Tip: To search several name patterns at once:
find /var/log -name "*.log" -o -name "*.txt"
-o means OR and combines criteria.
Search by type
Linux distinguishes file types. find can target them:
| Option | Finds | Example |
|---|---|---|
-type f |
Regular files | find /etc -type f |
-type d |
Directories | find /var -type d -name "log*" |
-type l |
Symbolic links | find /usr/bin -type l |
-type b |
Block devices | find /dev -type b |
-type c |
Character devices | find /dev -type c |
-type s |
Sockets | find /var/run -type s |
-type p |
Named pipes (FIFOs) | find /var -type p |
🔧 Practical example for system analysis:
# All symbolic links whose targets do not exist
find /usr/bin -type l -exec test ! -e {} \; -print
Search by size
Size search is useful for maintenance and disk analysis:
# Files larger than 100MB
find /home -type f -size +100M
# Files smaller than 10KB
find /var/log -type f -size -10k
# Exactly 0 bytes (empty files)
find /tmp -type f -size 0
Size units in find:
c: bytesk: kilobytes (1024 bytes)M: megabytes (1024 kilobytes)G: gigabytes (1024 megabytes)
Signs on a size have a specific meaning:
+means “greater than”-means “less than”- No sign means “exactly”
💡 Admin tip: To find the largest files and sort them by size:
find /var -type f -exec ls -lh {} \; | sort -k5,5hr | head -10
Search by modification date
Linux keeps three timestamps per file:
- Access time (atime): last read
- Modification time (mtime): last content change
- Change time (ctime): last metadata change (permissions, owner)
find can search by those timestamps:
# Changed in the last 7 days
find /var/log -type f -mtime -7
# Last accessed more than 30 days ago
find /home -type f -atime +30
# Created or changed in the last 24 hours
find /tmp -type f -mtime 0
Time values are in days:
+n: more than n days-n: fewer than n daysn: exactly n days
For finer control there are -mmin, -amin and -cmin:
# Changed in the last 30 minutes
find /var/log -type f -mmin -30
🔧 Practical example for log rotation:
# Delete log files older than 90 days
find /var/log -name "*.log" -type f -mtime +90 -exec rm {} \;
Run actions on found files
The real value of find is doing something with the hits. -exec runs any command on each found file:
# Delete all found files
find /tmp -name "*.tmp" -exec rm {} \;
# Change permissions on found files
find /var/www -type f -exec chmod 644 {} \;
# Show the contents of all found files
find /etc -name "*.conf" -exec cat {} \;
The -exec syntax:
{}is a placeholder for the path of the found file\;marks the end of the command
The command runs once per found file.
⚠️ Watch out:
-exec rmdeletes immediately with no confirmation.
💡 Efficiency tip:
-exec command {} \+runs the command once and passes all found files as arguments, which is often faster:
# Inefficient: grep is started once per file
find /var/log -name "*.log" -exec grep "error" {} \;
# Efficient: grep runs once with all files as arguments
find /var/log -name "*.log" -exec grep "error" {} \+
Powerful combinations with find
Using -exec for direct actions
-exec can run complex work inside find:
# Mark all text files that contain "TODO" and append them to a result file
find ~/projects -type f -name "*.txt" -exec grep -l "TODO" {} \; -exec echo "File: {}" >> ~/todo_list.txt \;
# Compress only files of a given user
find /home/username -type f -user username -exec gzip -9 {} \;
# Delete old backups, but list and confirm first
find /backup -type f -name "*.bak" -mtime +90 -exec ls -lh {} \; -exec rm -i {} \;
A useful pattern is a conditional test:
# Find empty directories and remove them
find /tmp -type d -empty -exec rmdir {} \;
# Find large log files and compress them
find /var/log -type f -name "*.log" -size +50M -exec gzip {} \;
🔧 Practical example for system maintenance:
# Temporary files older than 7 days
find /tmp -type f -mtime +7 -exec rm {} \;
# Core dumps: archive for later analysis
find / -name "core" -type f -exec mv {} /var/crashes/ \;
Combining with pipes for complex operations
For still more complex work, combine find with pipes:
# The 10 largest files under /var
find /var -type f -exec ls -lh {} \; | sort -k5hr | head -10
# Count PHP files in a project
find ~/projects -name "*.php" | wc -l
# All images, listed by size
find ~/pictures -name "*.jpg" -o -name "*.png" | xargs du -sh | sort -hr
xargs is especially useful with find: it turns command output into arguments for another command:
# Alternative to -exec with more control
find /var/log -name "*.log" | xargs grep "Critical Error"
# Safe for names with spaces
find /home -name "*.mp3" -print0 | xargs -0 cp -t /media/backup/music/
⚠️ Important: For names with spaces or special characters, use
-print0withfindand-0withxargs.
Practical examples for daily admin work
Find files with given permissions:
# All setuid files (potential security risk)
find /usr -type f -perm -4000
# All world-writable files
find /var -type f -perm -o=w
Find and remove duplicates:
# Potential duplicates by MD5
find . -type f -exec md5sum {} \; | sort | uniq -w32 -d
Find broken links:
# Symbolic links that point nowhere
find /usr/lib -type l -exec test ! -e {} \; -print
Disk-space analysis:
# Directories that use more than 1GB
find / -type d -exec du -sh {} \; 2>/dev/null | grep -E "^[0-9]+G"
Automated file operations:
# Convert all .txt files to .md
find . -name "*.txt" -exec sh -c 'pandoc -f text -t markdown -o "${1%.txt}.md" "$1"' _ {} \;
💡 LPIC-1 exam tip: Know the basic
findcriteria (-name,-type,-size,-mtime) and how to use-exec. These show up often in practical questions.
Faster search with locate
find is powerful but can be slow on large filesystems because it walks the tree live. locate is much faster for many searches.
Understanding database search
locate uses a pre-built index of the filesystem, which makes searches extremely fast:
locate sshd_config
# Output:
/etc/ssh/sshd_config
/usr/share/doc/openssh-server/examples/sshd_config
/usr/share/man/man5/sshd_config.5.gz
Unlike find, locate does not walk the live filesystem. It searches a database of paths, typically updated daily.
Advantages of locate:
- Extremely fast, even with millions of files
- Simple syntax
- Searches the whole filesystem with no start directory
Disadvantages of locate:
- Misses files created after the last database update
- Fewer filters than
find - Can still list files that have already been deleted
🔧 Practical example for comparison:
# find (can take minutes)
time find / -name "*.conf" 2>/dev/null
# locate (near-instant)
time locate "*.conf"
💡 Tip: Default
locatesearch is case-sensitive. Use-ifor a case-insensitive search:
locate -i README
Updating the database with updatedb
The locate database is usually updated daily by a cron job. If you need results for newly created files immediately, update it by hand:
sudo updatedb
⚠️ Note:
updatedbneeds administrator rights and can take several minutes depending on the system size.
updatedb is configured in /etc/updatedb.conf:
cat /etc/updatedb.conf
# Output:
PRUNEFS="NFS nfs nfs4 afs binfmt_misc proc smbfs autofs iso9660 ncpfs coda devpts ftpfs devfs mfs shfs sysfs cifs lustre tmpfs usbfs udf fuse.glusterfs fuse.sshfs curlftpfs ecryptfs fusesmb devtmpfs"
PRUNENAMES=".git .bzr .hg .svn .thumbnail"
PRUNEPATHS="/tmp /var/spool /media /var/lib/os-prober /var/lib/ceph"
PRUNEUID="33"
That configuration decides which filesystems, directories or names updatedb ignores.
💡 Admin tip: On systems with many temporary files or large development trees, tuning
/etc/updatedb.confimproves performance and saves space.
❗ Security note: Because
locatestores all paths in its database, ordinary users can see sensitive filenames even if they cannot read the files.
Finding executables and commands
Often you are not looking for arbitrary files, but for executables or their documentation. Linux has specialised tools for that.
which — find commands in PATH
which prints the full path of an executable found in PATH:
which python3
/usr/bin/python3
which -a python
/usr/bin/python
/bin/python
which is useful to find out:
- Which version of a command will run
- Whether a command is in PATH at all
- Whether an alias or another version takes precedence
-a shows every match in PATH, not only the first.
🔧 Practical example for administrators:
# Which Python versions are used by default
which python python2 python3
/usr/bin/python3
/usr/bin/python2
💡 Tip for shell scripts:
whichis useful in scripts to check whether a command exists:
# In a shell script:
if ! which docker > /dev/null 2>&1; then
echo "Docker is not installed!"
exit 1
fi
Finding commands, sources and man pages
whereis searches more broadly than which. It finds executables, man pages and sources:
whereis bash
bash: /bin/bash /etc/bash.bashrc /usr/share/man/man1/bash.1.gz
whereis -b python
python: /usr/bin/python /usr/bin/python2.7 /usr/bin/python3.8
Options for a targeted search:
-b: binaries only-m: man pages only-s: sources only
whereis -m python
python: /usr/share/man/man1/python.1.gz
⚠️ Important difference:
whichsearches only PATH.whereissearches the standard directories for binaries, man pages and source.
🔧 Practical example for documentation search:
# Man pages for all installed services
cd /etc/init.d && for s in *; do whereis -m $s; done | grep -v ": $"
💡 LPIC-1 exam tip: Know the differences between
whichandwhereisand when to use which. That can appear in exam questions.
Scenarios and practical examples
Typical administrator scenarios:
Scenario 1:
Solve disk-space problems
# The 20 largest files on the system
find / -type f -exec du -h {} \; 2>/dev/null | sort -hr | head -20
# Files larger than 1GB
find / -type f -size +1G -exec ls -lh {} \; 2>/dev/null
# Directories that use a lot of space
du -h --max-depth=2 /var | sort -hr | head -10
Scenario 2:
Find recently changed configuration files
# Configuration files changed in the last 24 hours
find /etc -name "*.conf" -type f -mtime 0
# Or with locate (after updatedb)
locate --regex "/etc/.*\.conf$" | xargs stat -c "%y %n" | grep "$(date +%Y-%m-%d)" | sort
Scenario 3:
Security audit
# SUID programs (potential risks)
find / -type f -perm -4000 -ls 2>/dev/null
# World-writable files in system directories
find /etc /bin /usr/bin /sbin -type f -perm -o=w -ls 2>/dev/null
Scenario 4:
Log analysis
# Yesterday’s Apache logs that contain errors
find /var/log/apache2 -name "*.log*" -mtime 1 -exec grep -l "error" {} \;
# The 10 largest log files
find /var/log -type f -name "*.log" -exec ls -lh {} \; | sort -k5hr | head -10
Scenario 5:
File cleanup
# Temporary files older than one week
find /tmp /var/tmp -type f -mtime +7 -delete
# Compress old log files
find /var/log -name "*.log" -mtime +30 -exec gzip {} \;
💡 Daily-work tip: Keep a file of useful
findcommands for recurring jobs:
cat > ~/admin_searches.sh << 'EOF'
#!/bin/bash
# Useful search helpers for admins
# Large files
find_large() {
find / -type f -size +${1:-100}M -exec ls -lh {} \; 2>/dev/null | sort -k5hr
}
# Recently changed configuration
find_recent_configs() {
find /etc -type f -name "*.conf" -mtime -${1:-1} -ls
}
# Files of a given user
find_user_files() {
find /home -user "$1" -type f -mtime -${2:-7} -ls
}
# Text in configuration files
find_in_configs() {
find /etc -type f -name "*.conf" -exec grep -l "$1" {} \;
}
EOF
chmod +x ~/admin_searches.sh
source ~/admin_searches.sh
With that script you can use these helpers in the shell:
| Command | Action |
|---|---|
find_large 500 |
Find large files |
find_recent_configs 2 |
Recently changed configs |
find_user_files john 3 |
Find a user’s files |
find_in_configs "ListenAddress" |
Find text in configs |
Mastering the different ways to find files is a basic admin skill. With these commands you can locate what you need — for daily work, troubleshooting or maintenance.
Comparing files
As a Linux administrator you often need to compare files — to trace configuration changes, review code updates or find faults. Linux has strong comparison tools.
Comparing text files
diff is the standard tool for comparing text files line by line. It is especially useful for configuration, scripts and source.
Basic syntax and output formats
Basic use is simple:
diff file1.txt file2.txt
Default diff output can look confusing at first:
3c3
< This is a line in file 1
---
> This is a changed line in file 2
6,8d5
< These lines
< exist only in
< file 1
10a8,9
> These lines
> exist only in file 2
The output uses special markers:
3c3means: line 3 in file 1 was changed to line 3 in file 2<marks: lines from the first file>marks: lines from the second file---separates: the blocks from first and second file6,8d5means: lines 6–8 in file 1 were deleted in file 210a8,9means: after line 10 in file 1, lines 8–9 were added in file 2
🔧 Practical example:
Two versions of an Apache configuration:
diff httpd.conf httpd.conf.new
44c44
< Listen 80
---
> Listen 8080
142,144d141
< <Directory "/var/www/special">
< AllowOverride All
< </Directory>
156a154,157
> <VirtualHost *:8080>
> DocumentRoot /var/www/new_site
> ServerName example.com
> </VirtualHost>
That output shows:
- The port changed from
80to8080 - A
Directoryblock was removed - A new
VirtualHostblock was added
⚠️ Exit status:
diffreturns 0 when there are no differences and 1 when there are. That is useful in scripts that check whether two files are identical.
diff file1.txt file2.txt > /dev/null
echo $? # 0 if identical, otherwise 1
Contextual differences
The default diff format can be hard to read. Two alternative formats add context:
1. Context format with -c:
diff -c httpd.conf httpd.conf.new
*** httpd.conf 2023-05-14 09:45:22.000000000 +0200
--- httpd.conf.new 2023-05-14 10:30:15.000000000 +0200
***************
*** 41,47 ****
ServerAdmin admin@example.com
ServerName example.com
! Listen 80
DocumentRoot "/var/www/html"
--- 41,47 ----
ServerAdmin admin@example.com
ServerName example.com
! Listen 8080
DocumentRoot "/var/www/html"
In this format:
*marks lines from the first file---marks lines from the second file!marks changed lines+marks added lines-marks deleted lines
2. Unified format with -u:
diff -u httpd.conf httpd.conf.new
--- httpd.conf 2023-05-14 09:45:22.000000000 +0200
+++ httpd.conf.new 2023-05-14 10:30:15.000000000 +0200
@@ -41,7 +41,7 @@
ServerAdmin admin@example.com
ServerName example.com
-Listen 80
+Listen 8080
DocumentRoot "/var/www/html"
Unified format is more modern and compact:
-marks lines only in the first file+marks lines only in the second file- Unchanged lines have no marker
@@ -41,7 +41,7 @@means: 7 lines from the first file starting at 41 are compared with 7 lines from the second file starting at 41
💡 Practice tip: Unified format (
-u) is the most common today, especially in version control such as Git. It is compact and still readable.
Comparing directories
diff can compare whole directory trees recursively:
diff -r directory1/ directory2/
That compares every file in both trees.
diff -r /etc/apache2/sites-available/ /etc/apache2/sites-available.bak/
Only in /etc/apache2/sites-available/: new_site.conf
diff -r /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available.bak/000-default.conf
25c25
< DocumentRoot /var/www/custom
---
> DocumentRoot /var/www/html
That output shows:
Only in /etc/apache2/sites-available/: new_site.conf→new_site.confexists only in the first directory- In
000-default.confDocumentRoot changed
For a cleaner comparison combine -r with other options:
diff -ur /etc/apache2/sites-available/ /etc/apache2/sites-available.bak/
⚠️ Watch out: On large trees a recursive compare can take a long time and produce a lot of output.
🔧 Practical example for system administration:
# Compare two configuration trees and store the differences
diff -ur /etc/nginx/ /etc/nginx.bak/ > nginx_changes.diff
💡 Tip: With
-q(quiet),diffonly reports which files differ, without the details:
diff -qr /etc/nginx/ /etc/nginx.bak/
Files /etc/nginx/nginx.conf and /etc/nginx.bak/nginx.conf differ
Only in /etc/nginx/sites-available: test.conf
Ignoring differences (whitespace, case)
In practice you often want to ignore some kinds of difference. diff has options for that:
| Option | Description | Use case |
|---|---|---|
-b |
Ignore changes in the amount of whitespace | Formatted text |
-w |
Ignore all whitespace | When only the text itself matters |
-i |
Ignore case | Case-insensitive compares |
-B |
Ignore blank lines | Differently formatted code |
-I REGEX |
Ignore lines matching a regular expression | Skip comment lines, for example |
🔧 Practical examples:
# Ignore whitespace-count differences
diff -b file1.txt file2.txt
# Ignore case and whitespace
diff -ib file1.txt file2.txt
# Ignore lines with timestamps (useful for logs)
diff -I '^\[.*\]' logfile1.log logfile2.log
# Ignore comment lines in configuration files
diff -I '^#' config1.conf config2.conf
💡 LPIC-1 exam tip: Know the common options, especially
-u(unified),-r(recursive) and-b(ignore whitespace). They show up in practical tasks.
Comparing binary files
diff is built for text. cmp is the tool for a byte-accurate compare, including binaries.
Byte-for-byte comparison
cmp compares files byte by byte and stops at the first difference:
cmp file1.bin file2.bin
file1.bin file2.bin differ: byte 327, line 4
That output tells you:
- The files differ
- The first difference is at byte 327, which is on line 4
💡 Note: If there is no output, the files are identical.
For a more detailed analysis use -l (verbose):
cmp -l file1.bin file2.bin
327 141 142
328 142 143
329 143 144
That output shows:
- The byte position (
327,328,329) - The byte value in the first file (octal:
141,142,143) - The byte value in the second file (octal:
142,143,144)
🔧 Practical example for system administration:
# Check whether two binaries are identical
if cmp -s binary1.bin binary2.bin; then
echo "The files are identical."
else
echo "The files differ."
fi
-s (silent) suppresses output and only sets the exit status.
Differences from diff
The main differences between cmp and diff:
| Property | cmp |
diff |
|---|---|---|
| How it works | Byte-for-byte | Line-by-line |
| File types | Any file type | Primarily text |
| Output | First difference only | All differences |
| Detail | Byte position and value | Line differences with context |
| Purpose | Check identity | Analyse and apply differences |
⚠️ Note: On very large files
cmpis often faster thandiffbecause it can stop at the first difference.
💡 Practice tip: Use
cmp -sfor fast identity checks in scripts anddifffor detailed analysis.
# Fast identity check with cmp
cmp -s file1 file2 && echo "Identical" || echo "Different"
# Detailed analysis with diff
diff -u file1 file2 > differences.txt
Creating and applying patches
One of the strongest uses of diff is creating and applying patches — a way to store changes between files and apply them elsewhere.
Creating patches with diff
A patch is essentially diff output stored in a file:
diff -u original.conf changed.conf > changes.patch
Unified format (-u) is ideal for patches because it includes context that patch needs.
For directories, combine -u and -r:
diff -ur original_directory/ changed_directory/ > directory_changes.patch
🔧 Practical example
Store configuration changes as a patch:
# Backup of the original configuration
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.orig
# Edit the configuration
sudo nano /etc/ssh/sshd_config
# Create a patch of the changes
sudo diff -u /etc/ssh/sshd_config.orig /etc/ssh/sshd_config > ssh_changes.patch
# Show the patch
cat ssh_changes.patch
--- /etc/ssh/sshd_config.orig 2023-05-14 11:30:22.000000000 +0200
+++ /etc/ssh/sshd_config 2023-05-14 11:45:15.000000000 +0200
@@ -22,7 +22,7 @@
# Authentication:
LoginGraceTime 120
-PermitRootLogin prohibit-password
+PermitRootLogin no
StrictModes yes
# Logging
Such a patch can be documented, shared with colleagues or stored in version control.
Applying patches with patch
patch applies the changes stored in a patch file to a file or a directory:
patch < changes.patch
If the patch covers several files or directories, run patch in the parent directory.
🔧 Practical example
Apply a patch on a production system:
# Back up the current configuration
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
# Apply the patch
sudo patch /etc/ssh/sshd_config < ssh_changes.patch
patching file /etc/ssh/sshd_config
# Check the result
diff /etc/ssh/sshd_config.bak /etc/ssh/sshd_config
⚠️ Watch out: Always take a backup before you apply a patch, especially to system configuration.
Important patch options:
| Option | Description | Use case |
|---|---|---|
-p[num] |
Strip [num] leading directories from path names |
Patches from other directory layouts |
-b |
Create backups of the original files | Safety on critical changes |
--dry-run |
Simulate without changing files | Test whether the patch applies |
-R |
Apply the patch in reverse (undo) | Take changes back |
💡 Practice tip:
-pis especially important for patches from other sources:
# Strip the first directory from the path names
patch -p1 < /tmp/foreign.patch
That is often needed when the patch was created in a different tree.
Typical use cases in system administration
1. Standardised configuration changes
# Patch for an optimised Apache configuration
diff -u /etc/apache2/apache2.conf.original /etc/apache2/apache2.conf.optimized > apache_tuning.patch
# Apply that patch on other servers
ssh server2 "cat > /tmp/apache_opt.patch" < apache_tuning.patch
ssh server2 "cd / && sudo patch -p0 < /tmp/apache_opt.patch"
2. Script bug fixes
# Patch for a faulty script
diff -u script.sh.broken script.sh.fixed > script_fix.patch
# Document the fault and the fix in the patch
echo "# This patch fixes a date-calculation bug" > fix_with_docs.patch
echo "# Problem: wrong format in strftime()" >> fix_with_docs.patch
cat script_fix.patch >> fix_with_docs.patch
3. Undo temporary changes
# Apply a patch
patch < change.patch
# Later: reverse the changes
patch -R < change.patch
4. Configuration management in teams
# Admin A creates a change and shares it as a patch
diff -u nginx.conf.orig nginx.conf > performance_tuning.patch
# Admin B reviews the patch before applying
patch --dry-run < performance_tuning.patch
# After review: apply with a backup
patch -b < performance_tuning.patch
💡 LPIC-1 exam tip: Know the basics of creating patches with
diff -uand applying them withpatch. The exam often ties this to configuration management and troubleshooting.
Advanced comparison tools
Beyond diff and cmp, Linux has specialised tools for more complex compares.
Overview of diff3, vimdiff and meld
1. diff3 for a three-way compare
diff3 compares three files, which is useful when merging changes from two sources:
diff3 my_version.txt original.txt your_version.txt
Especially helpful for merge conflicts in version control.
2. vimdiff for a visual compare in the terminal
vimdiff is a strong tool for visual compare and edit in the terminal:
vimdiff file1.txt file2.txt
That opens both files side by side in vim and highlights differences. You can edit and merge directly.
Useful keys in vimdiff:
]c— next difference[c— previous differencedo— “diff obtain” — take the change from the other filedp— “diff put” — send the change to the other file:diffupdate— refresh the difference highlighting
🔧 Practical example for configuration management:
# Compare and edit two configuration files
vimdiff /etc/nginx/nginx.conf /etc/nginx/nginx.conf.new
3. meld for a graphical compare
On systems with a GUI, meld is an excellent tool with a clear interface:
meld file1.txt file2.txt
or for directory compares:
meld directory1/ directory2/
meld offers:
- Colour-coded differences
- Line-by-line merge with clicks
- Three-way compare
- Directory compare with a visual tree
⚠️ Note:
meldneeds a graphical session and is not installed by default on every system.
# Debian/Ubuntu
sudo apt install meld
# RHEL/CentOS/Fedora
sudo dnf install meld
💡 Admin tip: Install and learn at least one visual compare tool such as vimdiff. The time saved on complex file compares pays for the learning.
Practical use cases for file comparison
Typical Linux-admin uses:
1. Configuration management and review
# Compare the active configuration with the package default
diff -u /etc/ssh/sshd_config /etc/ssh/sshd_config.dpkg-dist
# Check changes after an upgrade
diff -u /etc/mysql/my.cnf.dpkg-old /etc/mysql/my.cnf
2. Troubleshooting by comparing configurations
# Compare a working server with a broken one
scp problemhost:/etc/apache2/apache2.conf /tmp/problem.conf
diff -u /etc/apache2/apache2.conf /tmp/problem.conf
3. Backup verification
# Check whether a backup is complete
diff -r /var/www/ /mnt/backup/www/
4. Compliance and security checks
# Compare the current file with a known-good hardened configuration
diff -u /etc/apache2/apache2.conf /usr/share/hardening/apache2_secure.conf
5. Fault analysis in log files
# Compare logs before and after a fault
diff -u /var/log/apache2/error.log.1 /var/log/apache2/error.log
🔧 Practical example for automated monitoring:
#!/bin/bash
# Daily check of critical configuration files
# Files to watch
FILES="/etc/ssh/sshd_config /etc/apache2/apache2.conf /etc/mysql/my.cnf"
# Compare each file against yesterday’s copy
for file in $FILES; do
if [ -f "$file.yesterday" ]; then
if ! diff -q "$file" "$file.yesterday" > /dev/null; then
echo "WARNING: $file has changed since yesterday!"
diff -u "$file.yesterday" "$file"
fi
fi
# Snapshot for tomorrow
cp "$file" "$file.yesterday"
done
💡 LPIC-1 exam tip: Know the basic differences between the comparison commands and when each tool fits:
difffor text files and to see the differencescmpfor binaries and fast identity checkspatchto apply changesAlso know how to ignore differences (
-b,-i,-w).
With this section you can spot, analyse and manage differences between files — a core Linux-admin skill for daily work, troubleshooting and the LPIC-1 certification.
Why this matters for LPIC-1
The ability to view, edit and compare file contents is a core part of LPIC-1 for several reasons.
Exam relevance
- Exam weight: On LPIC-1 exam 101 text processing and file management are about 20–25% of the questions
Practical tasks:
- The exam often uses scenarios where you must extract information from configuration files or change them with precision
Foundation for system administration:
- Because Linux stores almost all configuration as text, fluency with text tools is required for every administrator
💡 Exam tip: LPIC-1 often asks about:
- Using
less,headandtailto pull information on purpose- Efficient search with
findandlocate, and how they differ- Basic
vimcommands to edit, save and quit- The differences between the file-comparison tools
That knowledge is not only exam material. It is daily Linux-admin work — configuring services, watching logs and automating with scripts.
💡 Note: Exam information and study resources are in the LPIC-1 navigation module.
Command Reference (Cheatsheet)
| Command | Syntax / use | Description and LPIC-1 relevance |
|---|---|---|
cat |
cat -n file |
Print a whole file (-n with line numbers) |
tac |
tac file |
Print a file in reverse line order |
head |
head -n 20 file |
First n lines (default: 10) |
tail |
tail -n 20 -f log |
Last n lines (-f live follow) |
less |
less file |
Interactive pager for large files (Space, b, /term, q) |
nano |
nano file |
Simple terminal editor (Ctrl+O save, Ctrl+X quit) |
vim |
vim file |
Modal editor (i insert, :w save, :q! discard) |
find |
find /path -name "*" |
Walk trees by criteria (-name, -type, -size, -mtime, -exec) |
locate |
locate file |
Fast index search via the mlocate database |
updatedb |
updatedb |
Refresh the locate database |
which |
which command |
Full path of a binary in PATH |
whereis |
whereis command |
Binaries, sources and man pages (-b, -m, -s) |
type |
type command |
Command type (alias, builtin, function or file) |
diff |
diff -u old new |
Line-by-line compare (-u unified diff) |
patch |
patch -p1 < fix.patch |
Apply a unified-diff patch |
cmp |
cmp file1 file2 |
Byte-for-byte compare of any two files, including binaries |
Further Resources
| Resource | Description |
|---|---|
| GNU Coreutils: Output of parts of files | Official GNU documentation for head, tail, cat and paging tools |
| Vim Official Documentation | Handbook, command overview and tutorials for Vim |
| GNU Findutils Reference | Authoritative manual for find, locate, updatedb and xargs |
| GNU Diffutils Manual | Full specification for diff, cmp, diff3 and patch creation |
| LPI: LPIC-1 Exam 101 Objectives | Official LPI objectives for module 101 (topic 103: GNU and Unix commands) |
Conclusion
The tools for viewing, editing, searching and comparing files are the backbone of Linux system administration. Whether you analyse logs live with less and tail -f, edit configuration in rescue mode with nano or vim, or ship configuration changes as a unified diff with patch: these tools are required on LPIC-1 exam 101 and in the datacentre.
💡 Practice tip: When you change files in
/etc, always make a working copy first (for examplecp config.conf config.conf.bak). Withdiff -u config.conf.bak config.confyou can verify the edits before you restart the service.
The next LPIC-1 module covers text processing with streams, pipes and filters: LPIC-1: Text Processing with Shell Commands – regular expressions and the tools grep, sed, awk, cut and sort.
Course overview: All LPIC-1 articles and modules