Author | Nejat Hakan |
nejat.hakan@outlook.de | |
PayPal Me | https://paypal.me/nejathakan |
Viewing and Editing Files
Introduction Viewing and Editing Files
Working effectively in a Linux environment fundamentally involves interacting with files. Configuration settings, system logs, user data, scripts, and source code are all stored in files. Therefore, the ability to view the contents of files accurately and efficiently, as well as modify them when necessary, is a cornerstone skill for any Linux user, developer, or system administrator.
Linux follows the "everything is a file" philosophy, meaning that many system resources, devices, and processes can be interacted with as if they were files in the filesystem. While this chapter focuses primarily on regular files containing text or data, the tools and concepts discussed are broadly applicable.
We will primarily focus on text files, which contain human-readable characters organized into lines. Examples include configuration files (like /etc/fstab
), shell scripts (.sh
files), source code (.c
, .py
, .java
files), and documentation (like README files). Binary files, on the other hand, contain non-human-readable data, such as compiled programs (executables), images, audio files, or compressed archives. While some tools might display something when used on binary files, the output is usually meaningless without specialized programs, and editing them with standard text editors will almost certainly corrupt them.
The Linux command line offers a powerful suite of tools for viewing and editing files. Viewers range from simple tools that dump the entire file content to the screen to sophisticated pagers that allow navigation and searching within large files. Text editors available range from simple, intuitive editors ideal for quick changes to extremely powerful, albeit complex, editors favoured by programmers and administrators for their efficiency and feature sets.
This section will guide you through the most common and useful command-line tools for viewing files (cat
, less
, more
, head
, tail
) and introduce you to two fundamental text editors (nano
, vim
). Mastering these tools will significantly enhance your productivity and confidence when working within the Linux terminal. We will also explore how to compare files to identify differences, a crucial task in configuration management and software development.
1. Viewing Files The Basics
Before you can edit a file, you often need to examine its contents. Linux provides several commands for this purpose, each suited to different scenarios. The most fundamental are cat
, more
, and less
.
cat
(Concatenate)
The cat
command is one of the most basic and frequently used commands. Its primary function, despite its name "concatenate," is often perceived as simply displaying the contents of one or more files directly to the standard output (usually your terminal screen).
Basic Usage
To display the content of a single file, simply provide the filename as an argument:
If filename.txt
contains:
The command cat filename.txt
will output:
Concatenating Files
True to its name, cat
can concatenate (link together) multiple files sequentially. If you provide more than one filename, cat
will display the content of the first file, immediately followed by the content of the second file, and so on.
This is particularly useful for combining files. You can redirect the output of the concatenation into a new file using the output redirection operator >
:
This command reads header.txt
, body.txt
, and footer.txt
in order and writes their combined content into complete_document.txt
, overwriting complete_document.txt
if it already exists. To append instead of overwriting, use >>
.
Useful Options
-n
or--number
: Prepend line numbers to each line of the output, including blank lines.-b
or--number-nonblank
: Prepend line numbers only to non-empty lines.-E
or--show-ends
: Display a$
character at the end of each line. This is useful for visualizing trailing whitespace or identifying line breaks.-T
or--show-tabs
: Display TAB characters as^I
. Useful for distinguishing tabs from spaces.
Limitations
The primary drawback of cat
is that it dumps the entire content of the file(s) to the screen without pausing. If you use cat
on a very large file, the text will scroll by extremely quickly, making it impossible to read the beginning unless you have a terminal with a very large scrollback buffer. For viewing large files interactively, pagers like less
or more
are far more suitable.
more
The more
command is a simple pager utility. It displays the content of a file one screenful at a time, pausing after each screenful and prompting the user to continue. This makes it suitable for reading larger files that don't fit entirely on the screen.
Basic Usage
more
will display the first screenful of large_file.log
. At the bottom of the screen, you will typically see --More--
followed by a percentage indicating how much of the file has been displayed.
Navigation
- Spacebar: Display the next screenful of text.
- Enter (Return) Key: Display the next single line of text.
q
orQ
: Quitmore
and return to the shell prompt./pattern
: Search forward for the specifiedpattern
. Pressn
to find the next occurrence.=
: Display the current line number.:f
: Display the current file name and line number.
Limitations
more
is quite basic. Its most significant limitation is that, in most standard implementations, it cannot scroll backward through the file. Once you have advanced past a section of text, you cannot easily go back up without quitting and restarting. Searching capabilities are also rudimentary compared to less
. Due to these limitations, less
is generally preferred over more
in modern Linux systems.
less
The less
command is a significantly more powerful and flexible pager than more
. Its name is a playful reference ("less is more"). It allows both forward and backward navigation, advanced searching, and various display options, making it the standard pager for viewing files, man pages, and other command outputs on most Linux systems.
Basic Usage
Similar to more
, less
will display the beginning of the file. However, it typically doesn't display a --More--
prompt unless it reaches the end of the file. It waits for your input to navigate. A key difference is that less
doesn't need to read the entire file before starting, making it faster for large files.
Navigation (Much More Extensive than more
)
- Spacebar or
f
orPageDown
: Move forward one screenful. b
orPageUp
: Move backward one screenful.- Enter (Return) Key or
j
orDownArrow
: Move forward one line. y
ork
orUpArrow
: Move backward one line.g
orHome
: Go to the beginning of the file.G
orEnd
: Go to the end of the file.q
orQ
orZZ
: Quitless
./pattern
: Search forward forpattern
. Case-sensitive by default. Pressn
for the next match,N
for the previous match.?pattern
: Search backward forpattern
. Case-sensitive by default. Pressn
for the next match (in the backward direction),N
for the previous match (in the forward direction).&pattern
: Display only lines that match the pattern. Enter&
again with no pattern to turn this off.
Useful Options and In-Viewer Commands
-N
or--LINE-NUMBERS
: Displays line numbers at the beginning of each line withinless
.-S
or--chop-long-lines
: Prevents long lines from wrapping. You can then use the left/right arrow keys to scroll horizontally.-i
or--ignore-case
: Makes searches case-insensitive (applies only after startingless
unless the-i
option is used when invoking the command). You can also toggle this withinless
by typing-i
.h
: Display a help screen summarizingless
commands.F
: Enter "follow" mode.less
will wait for more data to be appended to the file and display it as it arrives, similar totail -f
. PressCtrl+C
to stop following and return to normal navigation.
Advantages over more
- Backward scrolling (
b
,y
,k
,PageUp
,UpArrow
). - Doesn't need to read the entire file before displaying the first page.
- More powerful search capabilities (backward search, case-insensitivity toggle).
- Ability to view horizontally (
-S
option). - Follow mode (
F
command).
Because of its flexibility and power, less
is the recommended tool for interactively viewing files of any significant size on the command line.
Workshop Examining Log Files and Configuration
In this workshop, we will practice using cat
, more
, and less
to examine different types of files you might encounter.
Objective: Understand the behaviour of cat
, more
, and less
with small and large files, and practice basic navigation and options.
Steps:
-
Create Sample Files:
- Open your terminal.
- Create a small configuration-like file:
- Create a slightly longer file (e.g., a poem snippet):
echo "Shall I compare thee to a summer’s day?" > poem.txt echo "Thou art more lovely and more temperate:" >> poem.txt echo "Rough winds do shake the darling buds of May," >> poem.txt echo "And summer’s lease hath all too short a date;" >> poem.txt echo "Sometime too hot the eye of heaven shines," >> poem.txt echo "And often is his gold complexion dimm'd;" >> poem.txt echo "And every fair from fair sometime declines," >> poem.txt echo "By chance or nature’s changing course untrimm'd;" >> poem.txt
- Generate a larger file (e.g., repeating lines). We'll use a loop to create
large_file.txt
with 1000 lines:(Note:# This loop repeats the echo command 1000 times # Adjust the number (1000) if needed for testing performance for i in $(seq 1 1000); do echo "This is line number $i in the large file." >> large_file.txt done # Verify its size (optional) wc -l large_file.txt
wc -l
counts the lines in a file)
-
Using
cat
:- Display the small configuration file: (Observe how the entire file is printed to the terminal)
- Display the configuration file with line numbers:
- Display with line numbers, skipping blank lines:
- Concatenate the config and poem files:
- Try
cat
on the large file (be prepared for fast scrolling!): (Notice how it scrolls past very quickly, making it hard to read the beginning unless your terminal has good scrollback)
-
Using
more
:- View the large file using
more
: - Press the Spacebar several times to advance page by page.
- Press Enter several times to advance line by line.
- Try searching for a specific line number, e.g., line 500: Press
/
then typeline number 500
and press Enter. - Try to scroll back up (you likely can't).
- Press
q
to exitmore
.
- View the large file using
-
Using
less
:- View the large file using
less
: - Press the Spacebar to move forward a page.
- Press
b
to move backward a page. Observe that you can scroll up! - Use the DownArrow or
j
to move down line by line. - Use the UpArrow or
k
to move up line by line. - Go to the end of the file by pressing
G
. - Go back to the beginning by pressing
g
. - Search forward for "line number 888": Press
/
, typeline number 888
, press Enter. Pressn
to find the next (if any),N
for the previous. - Search backward for "line number 100": Press
?
, typeline number 100
, press Enter. Pressn
(next match going up),N
(next match going down). - Quit
less
by pressingq
. - View the file again, this time with line numbers enabled from the start: (Observe the line numbers)
- Press
q
to exit.
- View the large file using
-
Clean up (Optional):
- Remove the sample files if you no longer need them:
This workshop demonstrated the core differences between cat
, more
, and less
. You saw that cat
is best for small files or concatenation, while less
provides the most versatile and user-friendly experience for interactively viewing files of any size.
2. Viewing Specific File Sections
Sometimes, you don't need to see the entire content of a file. You might only be interested in the first few lines (e.g., to check headers or initial settings) or the last few lines (e.g., to see the most recent entries in a log file). The head
and tail
commands are designed specifically for these tasks.
head
The head
command, as its name suggests, displays the beginning portion (the "head") of a file. By default, it shows the first 10 lines.
Basic Usage
To display the first 10 lines of a file:
Specifying the Number of Lines
You can easily change the number of lines displayed using the -n
option, followed by the desired number of lines.
To display the first 5 lines:
Alternatively, you can use a shorthand notation (though -n
is generally clearer):
Specifying the Number of Bytes
Instead of lines, you can ask head
to display a specific number of bytes from the beginning of the file using the -c
(bytes) option. This can be useful for binary files or when line endings are inconsistent.
To display the first 100 bytes:
(Note: This might cut off in the middle of a line.)Use Cases for head
- Quickly checking the structure or headers of a file (e.g., CSV file columns, script interpreters like
#!/bin/bash
). - Getting a sample of data from the beginning of a large dataset.
- Verifying that a file is not empty or contains the expected starting content.
tail
The tail
command is the counterpart to head
. It displays the ending portion (the "tail") of a file. By default, like head
, it shows the last 10 lines.
Basic Usage
To display the last 10 lines of a file:
Specifying the Number of Lines
Similar to head
, you can use the -n
option to specify the number of lines to display from the end.
To display the last 20 lines:
Shorthand notation also works:
Specifying the Number of Bytes
You can display a specific number of bytes from the end of the file using the -c
option:
To display the last 200 bytes:
The Power of -f
(Follow)
One of the most powerful and frequently used features of tail
is the -f
or --follow
option. When used, tail
displays the last few lines of the file (10 by default, or as specified by -n
) and then waits. If new lines are added to the end of the file, tail -f
automatically displays them on your terminal in real-time.
sudo
permissions to read system log files like /var/log/syslog
)
This is invaluable for monitoring log files or any file that grows over time (e.g., application output, sensor readings). tail -f
will continue running and displaying new lines until you explicitly stop it by pressing Ctrl+C
.
If the file being followed is rotated or renamed (a common practice for log files), the standard tail -f
might stop working or keep following the old, now-inactive file handle. To handle this more robustly, you can use tail -F
. This option is equivalent to using --follow=name --retry
, which means it follows the filename rather than the file descriptor, periodically checking if the file has been recreated or renamed and reopening it if necessary.
Use Cases for tail
- Checking the most recent entries in log files (
/var/log/syslog
, application logs, web server logs). - Monitoring the progress of scripts or processes that append output to a file.
- Verifying the end structure or footer of a file.
- Real-time monitoring using
tail -f
ortail -F
.
Workshop Monitoring System Activity
In this workshop, we'll use head
and tail
to examine parts of files, focusing on the practical use of tail -f
for monitoring changes.
Objective: Practice using head
and tail
with line/byte counts and master the use of tail -f
for real-time monitoring.
Steps:
-
Prepare a File to Monitor:
- We'll reuse the
large_file.txt
from the previous workshop or create a new dummy log file. Let's create a new one for clarity:echo "[INFO] Service started at $(date)" > my_app.log echo "[DEBUG] Initializing components..." >> my_app.log echo "[WARN] Configuration value 'timeout' not set, using default 30s." >> my_app.log echo "[INFO] Component A initialized." >> my_app.log echo "[INFO] Component B initialized." >> my_app.log echo "[DEBUG] Ready to accept connections." >> my_app.log
- We'll reuse the
-
Using
head
:- Display the default first 10 lines (which will be the whole file in this case):
- Display only the first 3 lines:
- Display the first 50 bytes: (Observe how it might cut off mid-line)
-
Using
tail
:- Display the default last 10 lines (again, the whole file initially):
- Display only the last 4 lines:
- Display the last 100 bytes:
-
Using
tail -f
(Real-time Monitoring):- Open two terminals. Arrange them so you can see both.
- In Terminal 1: Start monitoring the
my_app.log
file. We'll ask for the last 5 lines initially and then follow: (Terminal 1 will display the last 5 lines and then pause, waiting for changes.) - In Terminal 2: Append new lines to the log file using
echo
with the>>
append operator. Execute these commands one by one and watch Terminal 1 update immediately after each command:(Observe how each new line appears in Terminal 1 almost instantly after being added in Terminal 2.)echo "[INFO] Received connection from 10.0.2.15" >> my_app.log sleep 2 # Pause for 2 seconds echo "[ERROR] Failed to process request ID 12345: Disk full" >> my_app.log sleep 2 echo "[DEBUG] Connection from 10.0.2.15 closed." >> my_app.log sleep 2 echo "[WARN] High memory usage detected." >> my_app.log
- In Terminal 1: Stop the
tail -f
command by pressingCtrl+C
.
-
(Optional) Simulate Log Rotation with
tail -F
:- In Terminal 1: Start monitoring with
tail -F
: - In Terminal 2: Simulate log rotation by renaming the current log and creating a new one, then adding a line:
- In Terminal 1: Observe
tail -F
. It should detect the file change and start showing the content of the newmy_app.log
. If you had used only-f
, it would likely have stopped showing updates after themv
command. - Press
Ctrl+C
in Terminal 1 to stoptail -F
.
- In Terminal 1: Start monitoring with
-
Clean up (Optional):
- Remove the sample log files:
This workshop highlighted how head
and tail
allow you to efficiently inspect the beginnings and ends of files. Crucially, you experienced the power of tail -f
and tail -F
for real-time monitoring, a vital technique for system administration and debugging.
3. Simple Command Line Editing with nano
Viewing files is essential, but often you'll need to modify them. This could involve changing configuration settings, writing scripts, taking notes, or editing source code directly on a server where graphical tools aren't available. The command line offers several text editors. We'll start with nano
, which is known for its simplicity and ease of use, making it an excellent choice for beginners or for quick edits.
nano
(often a free clone or improvement of the earlier pico
editor) presents a straightforward interface with commonly used commands displayed at the bottom of the screen.
Starting nano
There are two main ways to start nano
:
-
Editing an existing file or creating a new one:
Iffilename.txt
exists,nano
will open it for editing. If it doesn't exist,nano
will start with an empty buffer, and when you save, it will usefilename.txt
as the default name. -
Opening an empty editor:
This startsnano
with an empty, unnamed buffer. You'll need to provide a filename when you save.
The nano
Interface
When you open nano
, you'll see:
- Top Line: Shows the
nano
version, the filename being edited (or "New Buffer"), and whether the file has been modified. - Main Area: This is where the file content is displayed and where you type your text.
- Bottom Lines (Shortcut Bar): This is the most distinctive feature for beginners. It lists the most common commands available, along with their keyboard shortcuts. The
^
symbol represents theCtrl
key (e.g.,^X Exit
means pressCtrl+X
). TheM-
symbol (Meta) usually represents theAlt
key (or sometimesEsc
followed by the key, e.g.,M-U Undo
might beAlt+U
orEsc
thenU
).
Basic Navigation
Moving around within the file in nano
is intuitive and uses common keys:
- Arrow Keys: Up, Down, Left, Right move the cursor accordingly.
PageUp
/PageDown
: Move up or down one screenful.Home
/End
: Move to the beginning or end of the current line. (May depend on terminal emulation;Ctrl+A
for beginning andCtrl+E
for end of line often work universally).Ctrl+_
(Control + Underscore): Go to a specific line number.nano
will prompt you to enter the line number (and optionally, column number).
Basic Editing
- Typing: Simply type characters, and they will be inserted at the cursor position.
- Backspace: Deletes the character before the cursor.
- Delete: Deletes the character under the cursor.
Saving Files (WriteOut
)
To save your changes (or save a new file), use the "WriteOut" command:
- Press
Ctrl+O
. nano
will display a prompt at the bottom, "File Name to Write:", usually pre-filled with the current filename (or blank if you startednano
without a filename).- You can modify the filename if needed.
- Press Enter to confirm and save the file. You'll see a confirmation message like "[ Wrote 15 lines ]".
If you try to exit without saving changes, nano
will prompt you.
Exiting nano
To exit the editor:
- Press
Ctrl+X
. - If you have unsaved changes,
nano
will ask "Save modified buffer?".- Press
Y
for Yes (it will then prompt for a filename if needed, similar toCtrl+O
). - Press
N
for No (discard changes). - Press
Ctrl+C
to Cancel exiting and return to the editor.
- Press
- If there are no unsaved changes, or after you've answered the save prompt,
nano
will close and return you to the shell prompt.
Cutting, Copying, and Pasting
nano
uses the concept of a "cut buffer" (like a clipboard) for moving and duplicating text.
- Marking Text:
- Move the cursor to the beginning of the text you want to select.
- Press
Ctrl+^
(Control + Shift + 6 on most keyboards) orAlt+A
to set the mark. - Use the arrow keys to move the cursor to the end of the desired selection. The selected text will be highlighted.
- Cutting Text (
Cut Text
):- To cut the current line (where the cursor is): Press
Ctrl+K
. The line disappears and is placed in the cut buffer. RepeatedCtrl+K
presses will cut subsequent lines and append them to the buffer. - To cut the marked selection: After marking text (see above), press
Ctrl+K
. The selected text is cut and placed in the cut buffer.
- To cut the current line (where the cursor is): Press
- Copying Text (
Copy Text
):- There isn't a direct single "copy" command for the current line like
Ctrl+K
for cut. - To copy the marked selection: After marking text, press
Alt+^
(Alt + Shift + 6) orEsc
then^
. The selected text remains in place but is copied to the cut buffer. (Note:Alt+6
is sometimes listed but often doesn't work as expected; marking is more reliable). - Alternatively, you can cut (
Ctrl+K
) the text you want to copy and then immediately paste it back (Ctrl+U
), leaving it in the cut buffer for further pasting.
- There isn't a direct single "copy" command for the current line like
- Pasting Text (
UnCut Text
):- Move the cursor to where you want to insert the text from the cut buffer.
- Press
Ctrl+U
. The content of the cut buffer will be inserted at the cursor position. You can pressCtrl+U
multiple times to paste the same content repeatedly.
Searching (Where Is
)
To search for text within the file:
- Press
Ctrl+W
(Where Is). nano
will prompt "Search:". Type the text you want to find and press Enter.- The cursor will jump to the first occurrence of the text found after the current cursor position.
- To find the next occurrence of the same text, press
Alt+W
(orEsc
thenW
). - Search is typically case-insensitive by default, but options exist to change this (often toggled with
Alt+C
or visible in theCtrl+W
menu via^T
options).
Other Useful Commands (Check the Shortcut Bar!)
Alt+U
orEsc
thenU
: Undo the last action.Alt+E
orEsc
thenE
: Redo the last undone action.Ctrl+T
: Execute Spell Check (if aspell package is installed).Ctrl+G
: Get Help (displays a list of commands).
nano
is a capable editor for many tasks, and its on-screen help makes it easy to learn the basics quickly.
Workshop Creating and Editing a Simple Script
In this workshop, you'll use nano
to create a basic shell script, practice editing, saving, and navigating.
Objective: Gain practical experience creating, editing, saving, navigating, and performing cut/paste operations within nano
.
Steps:
-
Create a New Script File:
- In your terminal, start
nano
to create a new file namedhello_world.sh
: (Notice the filename appears at the top, and the main area is empty)
- In your terminal, start
-
Add Script Content:
- Type the following lines into the
nano
editor:
- Type the following lines into the
-
Practice Navigation:
- Use the Arrow Keys to move the cursor around the text.
- Press
Ctrl+A
(orHome
) to go to the beginning of a line. - Press
Ctrl+E
(orEnd
) to go to the end of a line. - Use
PageUp
andPageDown
(though the file is short, try them). - Go to line 4: Press
Ctrl+_
, type4
, and press Enter. The cursor should move to theUSERNAME=...
line.
-
Save the File:
- Press
Ctrl+O
. - The prompt "File Name to Write: hello_world.sh" appears. Press Enter to confirm.
- Notice the confirmation message "[ Wrote 8 lines ]" at the bottom.
- Press
-
Make Further Edits (Cut and Paste):
- Let's move the comment line. Go to line 3 (
# Simple script...
). - Cut the entire line: Press
Ctrl+K
. The line disappears. - Move the cursor to line 2 (the blank line below
#!/bin/bash
). - Paste the cut line: Press
Ctrl+U
. The comment line should now appear on line 2.
- Let's move the comment line. Go to line 3 (
-
Make Further Edits (Copy and Paste via Mark):
- Let's copy the
echo "Have a great day!"
line. - Move the cursor to the beginning of line 8 (
echo "Have a great day!"
). - Set the mark: Press
Ctrl+^
(orAlt+A
). You should see "Mark Set" at the bottom. - Move the cursor to the end of the line (e.g., using
Ctrl+E
or arrow keys). The line should become highlighted. - Copy the marked text to the cut buffer: Press
Alt+^
(orEsc
then^
). You should see a message like "[ Copied 23 characters ]". The original line remains. - Move the cursor to the end of the file (e.g., press
Ctrl+E
on the last line, then press Enter to create a new line). - Paste the copied line: Press
Ctrl+U
. A duplicate of the "Have a great day!" line should appear.
- Let's copy the
-
Search for Text:
- Go to the beginning of the file (e.g.,
Ctrl+_
, type1
, Enter). - Search for the word "currently": Press
Ctrl+W
. - Type
currently
and press Enter. The cursor should jump to the line containing that word.
- Go to the beginning of the file (e.g.,
-
Undo/Redo:
- Let's undo the last paste: Press
Alt+U
(orEsc
thenU
). The second "Have a great day!" line should disappear. - Let's redo the paste: Press
Alt+E
(orEsc
thenE
). The line should reappear. - Undo it again (
Alt+U
).
- Let's undo the last paste: Press
-
Exit and Save:
- Press
Ctrl+X
to exit. nano
will ask "Save modified buffer?". PressY
.- It will confirm the filename "hello_world.sh". Press Enter.
- You should be back at the shell prompt.
- Press
-
Verify the File:
- Use
cat
orless
to view the final content of your script: - (Optional) Make the script executable and run it:
- Use
This workshop provided hands-on experience with the essential functions of nano
, demonstrating its suitability for creating and modifying text files directly from the command line.
4. Getting Started with Vim
While nano
is user-friendly, many experienced Linux users, system administrators, and programmers prefer more powerful editors like vim
or emacs
. vim
(Vi IMproved) is a highly configurable and efficient text editor built upon the older vi
editor, which is standard on nearly all Unix-like systems. vim
has a steeper learning curve than nano
primarily because it is a modal editor.
Understanding Vim Modes
Modal editing means that the editor behaves differently depending on which mode it is in. Keystrokes that type text in one mode might execute commands in another. This might seem confusing initially, but it allows for very efficient editing once mastered, as you don't constantly need to reach for modifier keys like Ctrl
or Alt
for common operations. The main modes you'll encounter initially are:
- Normal Mode: This is the default mode when you start
vim
. You cannot type text directly in this mode. Instead, keys correspond to commands: moving the cursor, deleting text, copying text, pasting text, switching to other modes, etc. Most of your time invim
is spent in Normal mode or transitioning briefly to other modes. - Insert Mode: This is the mode for actually typing text, similar to how a standard non-modal editor like
nano
or Notepad works. You enter Insert mode from Normal mode using commands likei
,a
,o
. - Visual Mode: Used for selecting blocks of text (character-wise, line-wise, or block-wise). Once text is selected, you can perform operations on it (like deleting, copying, or applying a command). You enter Visual mode from Normal mode using
v
,V
, orCtrl+v
. - Command-Line Mode (or Ex Mode): Used for entering more complex commands, saving files, quitting
vim
, searching, replacing text, and configuring settings. You enter Command-Line mode from Normal mode by pressing:
. The command you type appears at the bottom of the screen.
The key to using vim
effectively is knowing which mode you are in and how to switch between modes. The Esc
(Escape) key is your universal way back to Normal Mode from most other modes. If you're ever unsure what's happening, pressing Esc
a couple of times usually returns you to the safety of Normal Mode.
Starting vim
Similar to nano
:
- Editing an existing file or creating a new one:
- Opening an empty editor:
You will start in Normal Mode.
Basic Navigation (Normal Mode)
Navigation in vim
is designed to keep your hands on the home row of the keyboard. While arrow keys usually work, proficient vim
users primarily use:
h
: Move cursor leftj
: Move cursor downk
: Move cursor upl
: Move cursor rightw
: Move cursor forward to the start of the next word.b
: Move cursor backward to the start of the previous word.0
(zero): Move cursor to the beginning of the current line.^
: Move cursor to the first non-whitespace character of the current line.$
: Move cursor to the end of the current line.gg
: Go to the ginning (start) of the file (first line).G
: Go to the end of the file (last line).Ctrl+f
: Move forward one full screen (PageDown).Ctrl+b
: Move backward one full screen (PageUp).:N
: Go to line numberN
(e.g.,:10
goes to line 10). Type the colon, the number, then press Enter.
Switching Modes
- Normal -> Insert:
i
: Insert text before the cursor.a
: Append text after the cursor.I
: Insert text at the beginning of the current line.A
: Append text at the end of the current line.o
: Open a new line below the current line and enter Insert mode.O
: Open a new line above the current line and enter Insert mode.
- Insert -> Normal:
- Press
Esc
.
- Press
- Normal -> Visual:
v
: Enter character-wise Visual mode. Move cursor to select text.V
: Enter line-wise Visual mode. Selects whole lines.Ctrl+v
: Enter Visual block mode. Selects rectangular blocks.
- Visual -> Normal:
- Press
Esc
.
- Press
- Normal -> Command-Line:
- Press
:
(colon). Your cursor jumps to the bottom line, ready for a command.
- Press
- Command-Line -> Normal:
- Press
Esc
(sometimes twice if you've typed part of a command). Or press Enter to execute the command (which usually returns you to Normal mode).
- Press
Basic Editing (Normal Mode)
These commands are executed directly in Normal mode:
x
: Delete the character directly under the cursor.dw
: Delete word (from cursor to the start of the next word).dd
: Delete the entire current line.d$
: Delete from the cursor to the end of the line.d0
: Delete from the cursor (exclusive) to the beginning of the line.u
: Undo the last change. You can pressu
multiple times to undo multiple changes.Ctrl+r
: Redo the last undone change.
Combining Commands (The Vim Grammar): Many Vim commands follow a [action][motion]
pattern. For example, d
is the delete action, and w
is the motion to the next word. dw
deletes a word. d$
deletes to the end of the line. dG
deletes to the end of the file. d2j
deletes the current line and the 2 lines below it. This composability is a core part of Vim's power. c
is another action (change), so cw
changes (deletes and enters Insert mode) a word.
Saving and Quitting (Command-Line Mode)
These commands are typed after pressing :
in Normal Mode.
:w
: Write (save) the current file.:q
: Quitvim
. This only works if there are no unsaved changes.:wq
: Write (save) and then quit.:q!
: Quit without saving changes (force quit). Use with caution!:x
: Write (save) if the file has been modified, then quit. Similar to:wq
, but only writes if necessary.:w new_filename.txt
: Write the buffer content to a new file namednew_filename.txt
.:saveas new_filename.txt
: Save the buffer content to a new file and change the current buffer's filename to the new name.
Searching (Command-Line Mode)
/pattern
: Search forward forpattern
from the current cursor position. Press Enter to execute the search.n
: Find the next occurrence (in the forward direction).N
: Find the previous occurrence (in the backward direction).
?pattern
: Search backward forpattern
from the current cursor position. Press Enter.n
: Find the next occurrence (in the backward direction).N
: Find the previous occurrence (in the forward direction).
Search is typically case-sensitive by default. You can make it case-insensitive for a specific search by adding \c
after the pattern (e.g., /search\c
) or turn it on/off globally using command-line mode commands (:set ic
for ignore case, :set noic
for case-sensitive).
Getting Help
- Type
:help
in Normal mode to open Vim's extensive built-in help system. - Type
:help keyword
to get help on a specific topic or command (e.g.,:help dd
,:help modes
,:help :w
). - Use
Ctrl+[
orCtrl+T
within the help system to follow links and go back. - Type
:q
to close the help window. - Run
vimtutor
from your shell command line. This is an excellent interactive tutorial that guides you through the basics of Vim in about 30 minutes.
vim
is incredibly deep, and mastering it is a journey. Focus initially on basic navigation, switching between Normal and Insert modes, simple edits (x
, dd
, dw
), undo (u
), and saving/quitting (:w
, :q
, :wq
, :q!
).
Workshop Basic Vim Editing
In this workshop, you will use vim
to edit the hello_world.sh
script created earlier, practicing modal editing, navigation, basic edits, and saving/quitting.
Objective: Become comfortable with Vim's modes, basic Normal mode navigation and editing commands, and the save/quit process.
Steps:
-
Open the Script in Vim:
- In your terminal, open the script file: (You are now in Normal Mode)
-
Practice Normal Mode Navigation:
- Use
j
to move down a few lines. - Use
k
to move up a few lines. - Use
l
to move right,h
to move left along a line. - Go to the
USERNAME=
line. Pressw
several times to jump forward word by word. Pressb
several times to jump backward word by word. - Go to the end of the
USERNAME=
line by pressing$
. - Go to the beginning of that line by pressing
0
. - Go to the very last line of the file by pressing
G
. - Go to the very first line of the file by pressing
gg
.
- Use
-
Enter Insert Mode and Add Text:
- Navigate using
j
/k
to the blank line below#!/bin/bash
(likely line 3 if you followed the nano workshop structure). - Press
o
(lowercase 'o'). This should open a new line below the current one and switch you to -- INSERT -- mode (indicated at the bottom). - Type a new comment:
# This script was edited with Vim.
- Press
Esc
to return to Normal Mode. The-- INSERT --
indicator disappears.
- Navigate using
-
Perform Edits in Normal Mode:
- Navigate to the line
USERNAME="Student"
. - Move the cursor using
l
until it is over theS
inStudent
. - Delete the word "Student": Type
dw
. The word should disappear. You are still in Normal Mode. - Now, let's insert a different name. Press
a
(append). This enters Insert mode after the quote character. Type a new name, e.g.,VimUser
. - Press
Esc
to return to Normal Mode. The line should now look likeUSERNAME="VimUser"
- Go to the line
echo "Have a great day!"
. - Delete the entire line: Type
dd
. The line disappears. - Undo the deletion: Type
u
. The line reappears.
- Navigate to the line
-
Search:
- Go to the top of the file:
gg
. - Search for the word "echo": Press
/
, typeecho
, and press Enter. The cursor jumps to the first occurrence. - Find the next occurrence: Press
n
. - Find the next occurrence: Press
n
again. - Find the previous occurrence: Press
N
.
- Go to the top of the file:
-
Go to a Specific Line:
- Go to line 5: Press
:
, type5
, and press Enter. The cursor should jump to line 5.
- Go to line 5: Press
-
Save the File:
- Enter Command-Line mode: Press
:
. - Type
w
and press Enter. You should see a confirmation message like"hello_world.sh" [dos] 9L, 210C written
.
- Enter Command-Line mode: Press
-
Attempt to Quit Incorrectly:
- Make another small change. Go to the end of the file (
G
), presso
to open a new line and enter Insert mode, type# Final comment
, and pressEsc
to return to Normal mode. - Now try to quit: Press
:
, typeq
, and press Enter. - Observe the error message:
E37: No write since last change (add ! to override)
. Vim prevents you from accidentally losing changes.
- Make another small change. Go to the end of the file (
-
Quit Without Saving:
- Let's discard the last change ("# Final comment").
- Press
:
, typeq!
(quit, force), and press Enter. - You should be back at the shell prompt. The last comment you added will not be saved.
- Verify this using
cat
orless
: (Confirm the "# Final comment" line is not there, but the "VimUser" change is there because you saved after that edit)
-
Save and Quit:
- Open the file again:
vim hello_world.sh
- Go to the end (
G
), presso
, type# Final comment - take 2
, pressEsc
. - Save and quit in one command: Press
:
, typewq
(or:x
), and press Enter. - Verify again: (Now the final comment should be present)
- Open the file again:
This workshop introduced the modal nature of vim
and basic operations. Remember, vimtutor
is an excellent next step for reinforcing these concepts and learning more. Don't be discouraged by the initial learning curve; the efficiency gains are significant once you become comfortable.
5. Comparing Files with diff
When managing configuration files, source code, or documents, it's often crucial to know precisely how two versions of a file differ. The diff
command is the standard Linux utility for comparing files line by line and reporting the differences. Understanding diff
output is essential for tracking changes, merging work, and creating patches.
Purpose of diff
The diff
command compares two files, file1
and file2
, and outputs a set of instructions that describe how to transform file1
into file2
. This output indicates lines that need to be added, deleted, or changed.
Basic Usage
The simplest way to use diff
is:
The output describes the changes needed to make file1.txt
identical to file2.txt
.
Understanding Default diff
Output
The default output format can be a bit cryptic at first. It consists of one or more "hunks" of differences, each described by a change command. The format is generally:
[Line(s) in file1] [Action] [Line(s) in file2]
Followed by the actual lines involved, prefixed with:
<
: A line fromfile1
that needs to be removed or changed.>
: A line fromfile2
that needs to be added or is part of a change.---
: A separator between the lines fromfile1
andfile2
in a change (c
) operation.
Actions:
a
(Add): Lines need to be added tofile1
after the specified line number to matchfile2
. Format:LINE_IN_FILE1 a START_LINE_IN_FILE2,END_LINE_IN_FILE2
(or justSTART_LINE_IN_FILE2
if only one line is added).d
(Delete): Lines need to be deleted fromfile1
starting at the specified line number to matchfile2
. Format:START_LINE_IN_FILE1,END_LINE_IN_FILE1 d LINE_IN_FILE2
.c
(Change): The specified range of lines infile1
needs to be changed (replaced) to match the specified range of lines infile2
. Format:START1,END1 c START2,END2
.
Example:
Let's say file1.txt
contains:
And file2.txt
contains:
Running diff file1.txt file2.txt
would produce output similar to this:
Interpretation:
2c2
: This indicates a change needs to happen. Line 2 (2
) infile1
needs to be changed to match line 2 (2
) infile2
.< banana
: This line fromfile1
(line 2) needs to be removed/replaced.---
: Separator for the change.> blueberry
: This line fromfile2
(line 2) is the replacement.
3a4
: This indicates an addition needs to happen. After line 3 (3
) infile1
, lines need to be added to matchfile2
, specifically line 4 (4
) fromfile2
.> date
: This line fromfile2
(line 4) needs to be added after line 3 offile1
.
So, to change file1
to file2
, you replace line 2 ("banana") with "blueberry" and add line "date" after line 3 ("carrot").
The Unified Format (-u
)
The default diff
format is functional but often difficult to read quickly, especially for larger changes. The unified format, requested using the -u
option, is much more popular and generally easier to understand, especially in the context of version control systems (like Git) and patching.
Unified Format Output:
The unified format output starts with a header indicating the two files and their modification timestamps:
(---
indicates the original file, +++
indicates the new file)
This is followed by one or more "hunks". Each hunk starts with a line range indicator:
-START_LINE1,NUM_LINES1
: Specifies the starting line number and the total number of lines the hunk represents infile1
.+START_LINE2,NUM_LINES2
: Specifies the corresponding starting line number and number of lines infile2
.
Following the hunk header are the actual lines, prefixed with:
- (Space): A line that is common to both files (context line).
-
: A line that exists infile1
but not infile2
(a deletion).+
: A line that exists infile2
but not infile1
(an addition).
Example (Unified Format):
Using the same file1.txt
and file2.txt
as before:
Output:
--- file1.txt 2023-10-27 10:00:00.000000000 +0100
+++ file2.txt 2023-10-27 10:01:00.000000000 +0100
@@ -1,3 +1,4 @@
apple
-banana
+blueberry
carrot
+date
Interpretation (Unified):
- The header identifies the files.
@@ -1,3 +1,4 @@
: This hunk describes changes starting from line 1 infile1
(covering 3 lines total) and line 1 infile2
(covering 4 lines total).apple
: Line "apple" is unchanged context.-banana
: Line "banana" exists infile1
but notfile2
(it was removed/replaced).+blueberry
: Line "blueberry" exists infile2
but notfile1
(it was added/is the replacement).carrot
: Line "carrot" is unchanged context.+date
: Line "date" exists infile2
but notfile1
(it was added).
This format clearly shows additions and deletions relative to context lines, making it much easier to visualize the exact changes.
Other Useful Options
-c
(Context format): Another format that provides context lines, similar to unified but visually different. Less common now than-u
.-i
or--ignore-case
: Ignores differences in case when comparing lines.-w
or--ignore-all-space
: Ignores all whitespace (spaces and tabs) when comparing lines. Useful if only indentation or spacing changed.-B
or--ignore-blank-lines
: Ignores changes where lines are added or deleted if they are blank.-b
or--ignore-space-change
: Ignores changes in the amount of whitespace, but not the presence/absence of whitespace.-r
or--recursive
: When comparing directories,diff
will recursively compare correspondingly named files within those directories.--color
or--color=auto
: Produces colorized output (if supported by your terminal), making differences even easier to spot. (Availability may depend on yourdiff
version).
The output of diff
(especially in unified format) can be redirected to a file (.diff
or .patch
) and later applied to the original file using the patch
command to recreate the second file. This is fundamental to how software patches are distributed and how version control systems track changes.
Workshop Comparing Configuration File Versions
In this workshop, we'll create two versions of a mock configuration file and use diff
to identify the changes in both default and unified formats.
Objective: Practice using diff
to compare files, interpret both default and unified output formats, and use options to refine the comparison.
Steps:
-
Create
config_v1.txt
:- Use
nano
orvim
to create a file namedconfig_v1.txt
with the following content: - Save and exit the editor.
- Use
-
Create
config_v2.txt
(Modified Version):- First, copy the original file:
- Now, edit
config_v2.txt
usingnano
orvim
. Make the following changes:- Change
ListenPort = 80
toListenPort = 8080
. - Change
LogLevel = WARN
tologLevel = info
(note the case change). - Change
EnableSSL = false
toEnableSSL = true
. - Add a new line at the end:
AdminEmail = admin@example.com
. - Delete the
MaxClients = 100
line entirely.
- Change
- The final
config_v2.txt
should look like this: - Save and exit the editor.
-
Compare using Default
diff
Format:- Run the
diff
command: - Analyze the Output: Try to interpret the change commands (
c
,d
,a
) and the lines prefixed with<
and>
. It might look something like this (line numbers might vary slightly): (Relate this output back to the changes you made: changing port, deleting MaxClients, changing LogLevel and SSL, adding AdminEmail.)
- Run the
-
Compare using Unified
diff
Format (-u
):- Run
diff
with the-u
option: - Analyze the Unified Output:
(Notice how this format uses
--- config_v1.txt 2023-10-27 10:30:00.000000000 +0100 +++ config_v2.txt 2023-10-27 10:35:00.000000000 +0100 @@ -1,6 +1,6 @@ # Server Configuration v1 ServerName = main_server -ListenPort = 80 -MaxClients = 100 -LogLevel = WARN -EnableSSL = false +ListenPort = 8080 +logLevel = info +EnableSSL = true +AdminEmail = admin@example.com
+
for added lines and-
for deleted lines relative to the new file. See how clearly it shows the block of changes.)
- Run
-
Compare Ignoring Case (
-i
):- Remember we changed
LogLevel
tologLevel
. Let's see if-i
ignores this. - Analyze the Output: Observe the hunk related to the log level. Does it still show
LogLevel = WARN
being replaced bylogLevel = info
, or does it now treat them as more similar because the case difference of "LogLevel" vs "logLevel" is ignored? (It should still show a difference because "WARN" vs "info" is different, but the-i
focuses on the line comparison ignoring case). Correction: The-i
option applies to the entire line content comparison when deciding if lines are different. SoLogLevel = WARN
vslogLevel = info
are still different lines overall, even if the case of "LogLevel" itself is ignored. However, if the only difference wasLogLevel
vslogLevel
,-i
would make them appear the same. Let's test that.
- Remember we changed
-
Test Case-Insensitive Comparison More Directly:
- Create
config_v3.txt
based onv2
: - Edit
config_v3.txt
and only changelogLevel = info
back toLogLevel = info
(capital L). Save and exit. - Compare
v2
andv3
normally: (You should see the difference reported) - Compare
v2
andv3
ignoring case: (Now,diff
should report no differences because the only change was case, which-i
ignores)
- Create
-
Clean up (Optional):
- Remove the sample config files:
This workshop demonstrated how diff
is used to pinpoint changes between file versions. You saw the clarity advantage of the unified format (-u
) and how options like -i
can help tailor the comparison to ignore specific types of differences.
Conclusion
Mastering the command-line tools for viewing and editing files is fundamental to proficient Linux use. We began with basic file viewing using cat
, understanding its utility for small files and concatenation but recognizing its limitations for larger ones. We then explored the pagers more
and the significantly more powerful less
, highlighting the crucial navigation and search capabilities of less
that make it the preferred tool for interactive viewing.
We learned how head
and tail
provide efficient ways to inspect the beginning and end of files, respectively, with tail -f
(and tail -F
) being indispensable for real-time monitoring of log files and other growing data streams.
Moving to editing, we introduced nano
, a straightforward, beginner-friendly editor with on-screen help, ideal for quick configuration changes or simple script writing. We then delved into the basics of vim
, a powerful modal editor favored by many experienced users for its efficiency, despite its steeper learning curve. Understanding Vim's modes (Normal, Insert, Command-Line) and basic commands for navigation, editing, saving, and quitting forms a crucial foundation for leveraging its capabilities.
Finally, we explored the diff
command, learning how to compare file versions and interpret the output, particularly the widely used unified format (-u
), which clearly indicates additions and deletions. This skill is vital for tracking changes, collaborating on code, and managing system configurations.
The tools covered here – cat
, less
, head
, tail
, nano
, vim
, and diff
– form a core part of the Linux command-line toolkit. Continuous practice, especially with the editors nano
and vim
and the comparison tool diff
, will significantly enhance your productivity and confidence when working directly within the terminal environment. We encourage you to explore further options for these commands (man command_name
) and to practice using them in your daily interactions with the Linux system. For Vim users, completing the vimtutor
interactive tutorial is highly recommended.