---
id: 2025-05-16-lpic-1-viewing-and-editing-file-contents
slug: lpic-1-viewing-and-editing-file-contents
title: "LPIC-1: viewing and editing file contents"
excerpt: "Viewing, searching and comparing file contents: the Linux commands you need for daily administration and for LPIC-1."
date: "2025-05-16T07:50:29+02:00"
updated: "2025-05-16T07:50:29+02:00"
author:
  name: "Sebastian Palencsár"
  handle: "spalencsar"
category: "lpic-1-serie"
tags: ["lpic-1", "lpic-1-serie", "filemanagement", "findcommand", "diffcommand", "linuxcommands"]
reading_time: 45
toc: true
---

The first two [LPIC-1 modules](/en/category/lpic-1-serie){.badge-link-text} 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.

<blockquote class="infobox infobox--practice">
❗ **Important note:** As in the previous modules, this series does not replace an official exam-prep course for the [LPIC-1 certification](https://www.lpi.org/our-certifications/lpic-1-overview/){.badge-link-text}. It is a practice-oriented companion for self-study, so you can understand and apply the denser topics more reliably.
</blockquote>

## Why text processing sits at the centre of Linux

Linux follows the UNIX idea that <span class="nb-accent">everything is a file</span> — 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.

<span class="nb-accent">LPIC-1 relevance</span>

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.

<span class="nb-accent">What this module covers</span>

**The following sections cover:**

* Viewing file contents with `cat`, `less`, `more`, `head` and `tail`
* Editing text with editors such as nano and vim
* Finding files with `find`, `locate`, `which` and `whereis`
* Comparing files with `diff` and `cmp`

<blockquote class="infobox infobox--info">
💡 **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
</blockquote>

<span class="nb-accent">How to get the most from this module</span>

Run the commands in your own Linux environment while you read. Create test text files, try the viewers and editors, and watch the results.

<blockquote class="infobox infobox--info">
💡 **Tip:** For text editors, practice is not optional. Reading about vim commands is not the same as using them on a real file.
</blockquote>

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.

<span class="nb-accent">The `cat` command — show a whole file</span>

`cat` (from con**cat**enate) 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:

```bash
cat /etc/hosts
```

```bash
# 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
```

<span class="nb-accent">When should you use `cat`?</span>

**`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:**

```bash
# 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
```

<span class="nb-accent">Uses of cat beyond a simple dump</span>

`cat` can do more than print a file:

**Create or overwrite a file:**

```bash
$ cat > new_file.txt
This is a test.
This is the second line.

^D  # press Ctrl+D to end input
```

**Join files:**

```bash
$ cat file1.txt file2.txt > combined.txt
```

**Append to an existing file:**

```bash
cat update.txt >> logfile.txt
```

**Show binary files (usually not useful):**

```bash
cat /bin/ls | head
```

<blockquote class="infobox infobox--warn">
⚠️ **Important warning:** Be careful with `cat` on binary files or very large text files. You can stall the terminal or flood it with unreadable characters.
</blockquote>

<span class="nb-accent">Typical beginner mistake:</span>

Many newcomers use `cat` where a specialised tool is better:

```bash
# Inefficient (loads the whole file):
$ cat largefile.log | grep "Error"
```

```bash
# 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

<span class="nb-accent">What is `more` and why is it better for longer files?</span>

`more` is a pager that shows file contents one screen at a time — a clear improvement over `cat` for longer files:

```bash
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:**

```bash
$ more /etc/services
# Press Space to page
# Type /http and Enter to search for "http"
# Press q to leave
```

<span class="nb-accent">When to use `more`, and when not</span>

**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`

<blockquote class="infobox infobox--info">
💡 **Historical note:** `more` is one of the oldest UNIX pagers. `less` was added later as a more flexible successor. The name is a joke on “less is more” — and `less` really does more than `more`.
</blockquote>

### Advanced navigation with `less`

<span class="nb-accent">What makes `less` better than `more`?</span>

`less` is an extended `more` with two-way navigation and many extra features. It was built to remove the limits of `more`:

```bash
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`.

<span class="nb-accent">Navigation in less</span>

`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:**

```bash
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
```

<span class="nb-accent">Command-line options for less</span>

`less` also takes options at start:

```bash
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
```

<blockquote class="infobox infobox--info">
💡 **LPIC-1 exam tip:** `less` is the default pager for man pages. Learn the navigation keys. The exam can ask you to search and move efficiently in man pages.
</blockquote>

<span class="nb-accent">Why less matters for administrators</span>

**For Linux administrators `less` is essential for several reasons:**

**Efficiency on large files:**

* Unlike `cat` or `more`, `less` can 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, `less` never modifies the file

**Universality:**

* Works for text, binary files and even directories

<blockquote class="infobox infobox--warn">
⚠️ **Watch out:** Powerful as it is, `less` is not a substitute for `grep` on complex patterns or for `tail -f` when you need lasting log follow in scripts.
</blockquote>

### Show the first lines with `head`

<span class="nb-accent">What head offers and when to use it</span>

`head` is built to show the start of a file. By default it prints the first 10 lines:

```bash
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:

```bash
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:**

```bash
head -5 /etc/passwd  # first 5 lines
```

🔧 **Practical examples:**

**Check CSV headers:**

```bash
head -1 data.csv
ID,Name,Email,Department,Salary
```

**See the newest Git commits:**

```bash
git log | head -20
```

**Top processes by memory:**

```bash
$ ps aux | sort -rn -k 4 | head -5  # the 5 most memory-hungry processes
```

**Check several files at once:**

```bash
$ 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
```

<blockquote class="infobox infobox--info">
💡 **Advanced tip:** With `-c` you can show the first *n* bytes instead of lines:
</blockquote>

```bash
$ head -c 20 binary_file  # first 20 bytes
```

### Show the last lines with `tail`

<span class="nb-accent">The counterpart to head — why tail is indispensable</span>

`tail` is the counterpart to `head` and shows the last 10 lines by default:

```bash
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:

```bash
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:**

```bash
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:

```bash
tail -n +100 file.txt | head -n 10  # lines 100-109
```

<span class="nb-accent">The powerful `-f` (follow) option for live monitoring</span>

The most important `tail` option is `-f` (follow), which keeps printing new lines as they are appended:

```bash
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:**

```bash
# 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:**

```bash
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:**

```bash
$ 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:**

```bash
tail -f /var/log/syslog | grep --color "error\|warning\|critical"
```

Shows only new lines containing those words and highlights them.

<blockquote class="infobox infobox--warn">
⚠️ **Important warning:** Stop unused `tail -f` processes. Left running, they can hold file handles and interfere with log rotation.
</blockquote>

### Use cases and creative command combinations

The real skill is combining these basic commands into solutions for daily admin work.

<span class="nb-accent">Extract lines from the middle of a file</span>

```bash
# 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**

```bash
# 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**

```bash
# 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**

```bash
# 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**

```bash
# compare head and tail of a file
diff <(head datafile.txt) <(tail datafile.txt)
```

<blockquote class="infobox infobox--practice">
❗ **Typical mistake on large files:**
</blockquote>

```bash
# 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
```

<span class="nb-accent">UNIX philosophy in action</span>

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.

<blockquote class="infobox infobox--info">
💡 **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.
</blockquote>

## 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](https://www.lpi.org/our-certifications/exam-101-objectives/){.badge-link-text} topic.

### Text editor concepts on Linux

<span class="nb-accent">Why text editors sit at the centre of Linux administration</span>

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/interfaces` or `/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.

<span class="nb-accent">The two main categories of Linux text editors</span>

**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`

<blockquote class="infobox infobox--warn">
⚠️ **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.
</blockquote>

### 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 |

<blockquote class="infobox infobox--info">
💡 **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.
</blockquote>

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`

<span class="nb-accent">What is nano and why is it a good starting point?</span>

`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:**

```bash
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:**

```bash
# 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.

<span class="nb-accent">Basic navigation and editing in nano</span>

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:**

```bash
$ 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
```

<blockquote class="infobox infobox--practice">
❗ **Typical beginner mistake:** After editing a system configuration file you must restart the matching service or the change has no effect:
</blockquote>

```bash
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:

```bash
File Name to Write: file.txt
```

Press Enter to save under the same name, or type a new name to make a copy.

<blockquote class="infobox infobox--warn">
⚠️ **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”.
</blockquote>

**In that case:**

```bash
# 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:**

```bash
# 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"
```

<blockquote class="infobox infobox--info">
💡 **Practice tip:** Always take a backup before you edit a critical configuration file:
</blockquote>

```bash
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 `A` for “replace all” or confirm each change

<span class="nb-accent">Text formatting and manipulation</span>

| **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 |

<span class="nb-accent">Advanced features:</span>

| **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 |

<blockquote class="infobox infobox--warn">
⚠️ **Note:** Not every Alt combination works in every terminal emulator. In SSH sessions or some GUI terminals the system can swallow Alt keys.
</blockquote>

<blockquote class="infobox infobox--info">
💡 **Exam-prep tip:** For LPIC-1 you should know the basic nano shortcuts by heart, especially:
</blockquote>

| **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`

<span class="nb-accent">What is vim and why is the steep learning curve worth it?</span>

`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

```bash
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"
```

<span class="nb-accent">Understanding the modes — the key to vim</span>

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`, `o` or 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

```markdown
┌─────────────────────────────────────────────────────────────┐
│                    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) │     │
│   └─────────────────┘                     └───────────┘     │
└─────────────────────────────────────────────────────────────┘
```

<blockquote class="infobox infobox--warn">
⚠️ **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.
</blockquote>

🔧 **Practical example — first steps with vim:**

```markdown
┌─────────────────────────────────────────────────────────────┐
│                     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)            │
│                                                             │
└─────────────────────────────────────────────────────────────┘
```

<blockquote class="infobox infobox--info">
💡 **Short form:** `vim file.txt` → `i` → type text → `Esc` → `:w` → `:q`
</blockquote>

| **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 |

<blockquote class="infobox infobox--info">
💡 **Tip:** `:wq` saves and quits in one step.
</blockquote>

<span class="nb-accent">Basic navigation and editing in vim</span>

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 |

<blockquote class="infobox infobox--info">
💡 **Efficiency tip:** Many vim commands take a count:
</blockquote>

| **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 |

<span class="nb-accent">The real strength of vim: operators plus motions</span>

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.

<blockquote class="infobox infobox--practice">
❗ **Typical vim beginner mistake:** Forgetting to return to Normal mode before running commands. If your commands appear as text, press Esc.
</blockquote>

<span class="nb-accent">Search and replace</span>

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:**

```vim
:%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.

<blockquote class="infobox infobox--warn">
⚠️ **Regular expressions in vim:** Special characters such as `.`, `*`, `[`, `]` must be escaped with a backslash if you mean them literally.
</blockquote>

<span class="nb-accent">Save, quit and abort</span>

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 |

<blockquote class="infobox infobox--practice">
❗ **Classic beginner situation — “I cannot leave vim!”:**
</blockquote>

* Press `Esc` (to make sure you are in Normal mode)
* Type `:q!` and press `Enter`
* If that fails, try `:q` or `:wq`

This is common enough to be a meme. With practice, entering and leaving vim becomes automatic.

<blockquote class="infobox infobox--info">
💡 **Rescue tip:** If you opened a file in vim without write permission, you can still save with:
</blockquote>

```vim
:w !sudo tee %
```

That writes the file with root rights even if you started `vim` without `sudo`.

<span class="nb-accent">The most important vim commands for LPIC-1</span>

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, l` or arrow keys
* **By word**: `w` (forward), `b` (back)
* **Start/end of line**: `0` and `$`
* **Start/end of document**: `gg` and `G`
* **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

<span class="nb-accent">System-wide vs. user-specific configuration</span>

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 |

<blockquote class="infobox infobox--warn">
⚠️ **Important for administrators:** Changes to system-wide editor configs affect every user. Package updates can overwrite them.
</blockquote>

<span class="nb-accent">Useful configuration options for administrators</span>

<span class="nb-accent">Useful nano settings:</span>

```bash
# 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:

```bash
cat > ~/.nanorc << EOF
set autoindent
set linenumbers
set constantshow
set tabsize 4
set mouse
include "/usr/share/nano/*.nanorc"
EOF
```

<span class="nb-accent">Useful vim settings:</span>

```bash
# 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 `#`.

<blockquote class="infobox infobox--info">
💡 **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.
</blockquote>

🔧 **Practical example**

Set up an administrator-friendly vim environment:

```bash
# 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:

<span class="nb-accent">For nano:</span>

```bash
sudo nano /etc/nanorc

# Add the settings you want
```

<span class="nb-accent">For vim:</span>

```bash
sudo vim /etc/vim/vimrc.local

# On Debian/Ubuntu this file is sourced after /etc/vim/vimrc
```

<blockquote class="infobox infobox--warn">
⚠️ **Important:** System upgrades can overwrite system-wide configuration files.
</blockquote>

**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

<blockquote class="infobox infobox--info">
💡 **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.
</blockquote>

### 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:

```bash
# 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`).

<span class="nb-accent">Which editor for which job?</span>

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/vim` is almost everywhere; other editors may need installing

**Learning cost:**

* `nano` is learned in minutes; `vim` takes days to weeks for the basics, months for mastery

**Long-term productivity:**

* The investment in `vim` pays back in speed

**Team standards:**

* Admin teams often standardise on one editor for shared knowledge

<blockquote class="infobox infobox--info">
💡 **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.
</blockquote>

<blockquote class="infobox infobox--warn">
⚠️ **For LPIC-1:** Although nano is easier, you should know both editors for the exam. Tasks can require a specific editor.
</blockquote>

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.

<span class="nb-accent">Basic find syntax</span>

The basic pattern is:

```bash
find [start-directory] [options] [criteria] [action]
```

**A simple example:**

```bash
find /home/username -name "*.txt"
```

This searches `/home/username` and all subdirectories for names ending in `.txt`.

🔧 **Practical example with an explanation:**

```bash
find /etc -type f -name "*.conf" -size +10k
```

**That command means:**

* Search `/etc` and 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`:

```bash
# Exact name
find /var/log -name "syslog"

# Wildcards
find /home -name "*.jpg"

# Ignore case
find /var/www -iname "index.*"
```

<blockquote class="infobox infobox--warn">
⚠️ **Important:** Quote wildcards used with `find`, so the shell does not expand them before `find` sees them.
</blockquote>

<blockquote class="infobox infobox--practice">
❗ **Typical mistake:**
</blockquote>

```bash
find /home -name *.jpg    # WRONG: the shell expands *.jpg first
find /home -name "*.jpg"  # RIGHT: find processes the pattern
```

<blockquote class="infobox infobox--info">
💡 **Tip:** To search several name patterns at once:
</blockquote>

```bash
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:**

```bash
# 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:

```bash
# 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`: bytes
* `k`: 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”

<blockquote class="infobox infobox--info">
💡 **Admin tip:** To find the largest files and sort them by size:
</blockquote>

```bash
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:

```bash
# 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 days
* `n`: exactly n days

For finer control there are `-mmin`, `-amin` and `-cmin`:

```bash
# Changed in the last 30 minutes
find /var/log -type f -mmin -30
```

🔧 **Practical example for log rotation:**

```bash
# Delete log files older than 90 days
find /var/log -name "*.log" -type f -mtime +90 -exec rm {} \;
```

<span class="nb-accent">Run actions on found files</span>

The real value of `find` is doing something with the hits. `-exec` runs any command on each found file:

```bash
# 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.

<blockquote class="infobox infobox--warn">
⚠️ **Watch out:** `-exec rm` deletes immediately with no confirmation.
</blockquote>

<blockquote class="infobox infobox--info">
💡 **Efficiency tip:** `-exec command {} \+` runs the command once and passes all found files as arguments, which is often faster:
</blockquote>

```bash
# Inefficient: grep is started once per file
find /var/log -name "*.log" -exec grep "error" {} \;
```

```bash
# Efficient: grep runs once with all files as arguments
find /var/log -name "*.log" -exec grep "error" {} \+
```

### Powerful combinations with `find`

<span class="nb-accent">Using `-exec` for direct actions</span>

`-exec` can run complex work inside `find`:

```bash
# 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`:

```bash
# 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:**

```bash
# 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:

```bash
# 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:

```bash
# 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/
```

<blockquote class="infobox infobox--warn">
⚠️ **Important:** For names with spaces or special characters, use `-print0` with `find` and `-0` with `xargs`.
</blockquote>

<span class="nb-accent">Practical examples for daily admin work</span>

**Find files with given permissions:**

```bash
# 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:**

```bash
# Potential duplicates by MD5
find . -type f -exec md5sum {} \; | sort | uniq -w32 -d
```

**Find broken links:**

```bash
# Symbolic links that point nowhere
find /usr/lib -type l -exec test ! -e {} \; -print
```

**Disk-space analysis:**

```bash
# Directories that use more than 1GB
find / -type d -exec du -sh {} \; 2>/dev/null | grep -E "^[0-9]+G"
```

**Automated file operations:**

```bash
# Convert all .txt files to .md
find . -name "*.txt" -exec sh -c 'pandoc -f text -t markdown -o "${1%.txt}.md" "$1"' _ {} \;
```

<blockquote class="infobox infobox--info">
💡 **LPIC-1 exam tip:** Know the basic `find` criteria (`-name`, `-type`, `-size`, `-mtime`) and how to use `-exec`. These show up often in practical questions.
</blockquote>

### 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.

<span class="nb-accent">Understanding database search</span>

`locate` uses a pre-built index of the filesystem, which makes searches extremely fast:

```bash
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:**

```bash
# find (can take minutes)
time find / -name "*.conf" 2>/dev/null

# locate (near-instant)
time locate "*.conf"
```

<blockquote class="infobox infobox--info">
💡 **Tip:** Default `locate` search is case-sensitive. Use `-i` for a case-insensitive search:
</blockquote>

```bash
locate -i README
```

<span class="nb-accent">Updating the database with `updatedb`</span>

The `locate` database is usually updated daily by a cron job. If you need results for newly created files immediately, update it by hand:

```bash
sudo updatedb
```

<blockquote class="infobox infobox--warn">
⚠️ **Note:** `updatedb` needs administrator rights and can take several minutes depending on the system size.
</blockquote>

`updatedb` is configured in `/etc/updatedb.conf`:

```bash
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.

<blockquote class="infobox infobox--info">
💡 **Admin tip:** On systems with many temporary files or large development trees, tuning `/etc/updatedb.conf` improves performance and saves space.
</blockquote>

<blockquote class="infobox infobox--practice">
❗ **Security note:** Because `locate` stores all paths in its database, ordinary users can see sensitive filenames even if they cannot read the files.
</blockquote>

### Finding executables and commands

Often you are not looking for arbitrary files, but for executables or their documentation. Linux has specialised tools for that.

<span class="nb-accent">`which` — find commands in PATH</span>

`which` prints the full path of an executable found in `PATH`:

```bash
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:**

```bash
# Which Python versions are used by default
which python python2 python3
/usr/bin/python3
/usr/bin/python2
```

<blockquote class="infobox infobox--info">
💡 **Tip for shell scripts:** `which` is useful in scripts to check whether a command exists:
</blockquote>

```bash
# In a shell script:
if ! which docker > /dev/null 2>&1; then
    echo "Docker is not installed!"
    exit 1
fi
```

<span class="nb-accent">Finding commands, sources and man pages</span>

`whereis` searches more broadly than `which`. It finds executables, man pages and sources:

```bash
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

```bash
whereis -m python
python: /usr/share/man/man1/python.1.gz
```

<blockquote class="infobox infobox--warn">
⚠️ **Important difference:** `which` searches only PATH. `whereis` searches the standard directories for binaries, man pages and source.
</blockquote>

🔧 **Practical example for documentation search:**

```bash
# Man pages for all installed services
cd /etc/init.d && for s in *; do whereis -m $s; done | grep -v ": $"
```

<blockquote class="infobox infobox--info">
💡 **LPIC-1 exam tip:** Know the differences between `which` and `whereis` and when to use which. That can appear in exam questions.
</blockquote>

### Scenarios and practical examples

Typical administrator scenarios:

**Scenario 1:**

Solve disk-space problems

```bash
# 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

```bash
# 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

```bash
# 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

```bash
# 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

```bash
# 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 {} \;
```

<blockquote class="infobox infobox--info">
💡 **Daily-work tip:** Keep a file of useful `find` commands for recurring jobs:
</blockquote>

```bash
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.

<span class="nb-accent">Basic syntax and output formats</span>

Basic use is simple:

```bash
diff file1.txt file2.txt
```

Default `diff` output can look confusing at first:

```bash
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:**

* `3c3` **means**: line 3 in file 1 was **c**hanged 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 file
* `6,8d5` **means**: lines 6–8 in file 1 were **d**eleted in file 2
* `10a8,9` **means**: after line 10 in file 1, lines 8–9 were **a**dded in file 2

🔧 **Practical example:**

Two versions of an Apache configuration:

```bash
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 `80` to `8080`
* A `Directory` block was removed
* A new `VirtualHost` block was added

<blockquote class="infobox infobox--warn">
⚠️ **Exit status:** `diff` returns 0 when there are no differences and 1 when there are. That is useful in scripts that check whether two files are identical.
</blockquote>

```bash
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`:**

```bash
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`:**

```bash
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

<blockquote class="infobox infobox--info">
💡 **Practice tip:** Unified format (`-u`) is the most common today, especially in version control such as Git. It is compact and still readable.
</blockquote>

### Comparing directories

`diff` can compare whole directory trees recursively:

```bash
diff -r directory1/ directory2/
```

**That compares every file in both trees.**

```bash
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.conf` **exists only in the first directory**
* In `000-default.conf` **DocumentRoot changed**

**For a cleaner comparison combine `-r` with other options:**

```bash
diff -ur /etc/apache2/sites-available/ /etc/apache2/sites-available.bak/
```

<blockquote class="infobox infobox--warn">
⚠️ **Watch out:** On large trees a recursive compare can take a long time and produce a lot of output.
</blockquote>

🔧 **Practical example for system administration:**

```bash
# Compare two configuration trees and store the differences
diff -ur /etc/nginx/ /etc/nginx.bak/ > nginx_changes.diff
```

<blockquote class="infobox infobox--info">
💡 **Tip:** With `-q` (quiet), `diff` only reports which files differ, without the details:
</blockquote>

```bash
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:**

```bash
# 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
```

<blockquote class="infobox infobox--info">
💡 **LPIC-1 exam tip:** Know the common options, especially `-u` (unified), `-r` (recursive) and `-b` (ignore whitespace). They show up in practical tasks.
</blockquote>

### Comparing binary files

`diff` is built for text. `cmp` is the tool for a byte-accurate compare, including binaries.

<span class="nb-accent">Byte-for-byte comparison</span>

`cmp` compares files byte by byte and stops at the first difference:

```bash
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

<blockquote class="infobox infobox--info">
💡 **Note:** If there is no output, the files are identical.
</blockquote>

For a more detailed analysis use `-l` (verbose):

```bash
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:**

```bash
# 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 |

<blockquote class="infobox infobox--warn">
⚠️ **Note:** On very large files `cmp` is often faster than `diff` because it can stop at the first difference.
</blockquote>

<blockquote class="infobox infobox--info">
💡 **Practice tip:** Use `cmp -s` for fast identity checks in scripts and `diff` for detailed analysis.
</blockquote>

```bash
# 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.

<span class="nb-accent">Creating patches with `diff`</span>

A patch is essentially `diff` output stored in a file:

```bash
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`:**

```bash
diff -ur original_directory/ changed_directory/ > directory_changes.patch
```

🔧 **Practical example**

Store configuration changes as a patch:

```bash
# 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.

<span class="nb-accent">Applying patches with `patch`</span>

`patch` applies the changes stored in a patch file to a file or a directory:

```bash
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:

```bash
# 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
```

<blockquote class="infobox infobox--warn">
⚠️ **Watch out:** Always take a backup before you apply a patch, especially to system configuration.
</blockquote>

**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 |

<blockquote class="infobox infobox--info">
💡 **Practice tip:** `-p` is especially important for patches from other sources:
</blockquote>

```bash
# 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**

```bash
# 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**

```bash
# 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**

```bash
# Apply a patch
patch < change.patch

# Later: reverse the changes
patch -R < change.patch
```

**4. Configuration management in teams**

```bash
# 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
```

<blockquote class="infobox infobox--info">
💡 **LPIC-1 exam tip:** Know the basics of creating patches with `diff -u` and applying them with `patch`. The exam often ties this to configuration management and troubleshooting.
</blockquote>

### Advanced comparison tools

Beyond `diff` and `cmp`, Linux has specialised tools for more complex compares.

<span class="nb-accent">Overview of `diff3`, `vimdiff` and `meld`</span>

**1. `diff3` for a three-way compare**

`diff3` compares three files, which is useful when merging changes from two sources:

```bash
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:

```bash
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 difference
* `do` — “diff obtain” — take the change from the other file
* `dp` — “diff put” — send the change to the other file
* `:diffupdate` — refresh the difference highlighting

🔧 **Practical example for configuration management:**

```bash
# 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:

```bash
meld file1.txt file2.txt
```

**or for directory compares:**

```bash
meld directory1/ directory2/
```

**meld offers:**

* Colour-coded differences
* Line-by-line merge with clicks
* Three-way compare
* Directory compare with a visual tree

<blockquote class="infobox infobox--warn">
⚠️ **Note:** `meld` needs a graphical session and is not installed by default on every system.
</blockquote>

```bash
# Debian/Ubuntu
sudo apt install meld

# RHEL/CentOS/Fedora
sudo dnf install meld
```

<blockquote class="infobox infobox--info">
💡 **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.
</blockquote>

### Practical use cases for file comparison

Typical Linux-admin uses:

**1. Configuration management and review**

```bash
# 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**

```bash
# 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**

```bash
# Check whether a backup is complete
diff -r /var/www/ /mnt/backup/www/
```

**4. Compliance and security checks**

```bash
# 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**

```bash
# 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:**

```bash
#!/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
```

<blockquote class="infobox infobox--info">
💡 **LPIC-1 exam tip:** Know the basic differences between the comparison commands and when each tool fits:

* `diff` for text files and to see the differences
* `cmp` for binaries and fast identity checks
* `patch` to apply changes

Also know how to ignore differences (`-b`, `-i`, `-w`).
</blockquote>

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](/en/category/lpic-1-serie){.badge-link-text}.

## 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](https://learning.lpi.org/en/learning-materials/101-500/){.badge-link-text} 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

<blockquote class="infobox infobox--info">
💡 **Exam tip:** LPIC-1 often asks about:

* Using `less`, `head` and `tail` to pull information on purpose
* Efficient search with `find` and `locate`, and how they differ
* Basic `vim` commands to edit, save and quit
* The differences between the file-comparison tools
</blockquote>

That knowledge is not only exam material. It is daily Linux-admin work — configuring services, watching logs and automating with scripts.

<blockquote class="infobox infobox--info">
💡 **Note:** Exam information and study resources are in the [LPIC-1 navigation module](/en/lpic-1-serie/lpic-1-basic-navigation-and-filesystem-commands#resources-and-exam-information){.badge-link-text}.
</blockquote>

## 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](https://www.gnu.org/software/coreutils/manual/html_node/Output-of-parts-of-files.html){.badge-link-text} | Official GNU documentation for `head`, `tail`, `cat` and paging tools |
| [Vim Official Documentation](https://www.vim.org/docs.php){.badge-link-text} | Handbook, command overview and tutorials for Vim |
| [GNU Findutils Reference](https://www.gnu.org/software/findutils/manual/){.badge-link-text} | Authoritative manual for `find`, `locate`, `updatedb` and `xargs` |
| [GNU Diffutils Manual](https://www.gnu.org/software/diffutils/manual/){.badge-link-text} | Full specification for `diff`, `cmp`, `diff3` and patch creation |
| [LPI: LPIC-1 Exam 101 Objectives](https://www.lpi.org/our-certifications/exam-101-objectives/){.badge-link-text} | 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.

<blockquote class="infobox infobox--info">
💡 **Practice tip:** When you change files in `/etc`, always make a working copy first (for example `cp config.conf config.conf.bak`). With `diff -u config.conf.bak config.conf` you can verify the edits before you restart the service.
</blockquote>

The next LPIC-1 module covers text processing with streams, pipes and filters: [LPIC-1: Text Processing with Shell Commands](/en/online-courses/lpic-1-serie/2025/2025-05-28-lpic-1-text-processing-with-shell-commands){.badge-link-text} – regular expressions and the tools `grep`, `sed`, `awk`, `cut` and `sort`.

**Course overview:** [All LPIC-1 articles and modules](/en/category/lpic-1-serie){.badge-link-text}

