Linux Learning Chapter 5: Working with Text Files

📢 This article was translated by gemini-3-flash-preview

Chapter 5: Working with Text Files

Most Linux configuration is done by editing plain text files. Whether you’re modifying files in the /etc directory to configure local services or editing Ansible playbooks to manage hosts, plain text files are everywhere in these tasks.

5.1 Editing Files with vim and vi

vim is an improved version of vi. They work similarly, but vim includes features like tutorials and syntax highlighting. I recommend using vim.

In fact, in many Linux distributions, vi is just an alias for vim. Running alias vi usually outputs alias vi='vim', though the root user often doesn’t have this alias set.

Other text editors exist in Linux, such as nano, gedit, jed, joe, kate, kedit, mcedit, and nedit. Among these, jed and joe are common for plain text.

5.1.1 Getting Started with vi

vi has three modes: the primary ones are Command Mode and Input Mode, plus Ex Mode. By default, you enter a file in Command Mode (after running the vi file command).

Command Mode means you need to enter a command (one or two letters, sometimes with optional numeric parameters) to tell vi what you want to do before you can change any text.

Note: Commands are case-sensitive.

  1. Adding Text

To enter Input Mode, type an input command letter.

CommandDescription
aAppend command. Enter text to the right of the cursor.
AAppend at the end of the line. Start entering text at the end.
iInsert command. Enter text to the left of the cursor.
IInsert at the beginning of the line. Start at the start of the line.
oOpen below. Open a new line below the current one and enter Insert Mode.
OOpen above. Insert a new line above the current one and enter Insert Mode.

Once in Insert Mode, --INSERT-- will appear at the bottom of the screen.

After finishing your input, press Esc to return to Command Mode (sometimes you might need to press it twice).

  1. Moving in Text

Use these keys to move a single character:

KeyDescription
Arrow KeysUp, Down, Left, Right
h, j, k, lLeft, Down, Up, Right
Backspace, SpaceLeft, Right

Commands for moving multiple characters:

CommandDescription
wMove to the start of the next word (separated by space, tab, or punctuation).
WMove to the start of the next word (separated by space or tab).
bMove to the start of the previous word (space, tab, or punctuation).
BMove to the start of the previous word (space or tab).
0 (zero)Move to the start of the current line.
$Move to the end of the current line.
HMove to the top-left of the screen (first line on screen).
MMove to the first character of the middle line on the screen.
LMove to the bottom-left of the screen (last line on screen).
  1. Deleting, Copying, and Changing Text

These commands can be combined with movement keys (arrows, PgUp, PgDn, letters) and numbers to specify exactly what to delete, copy, or change.

CommandDescription
xDelete character under cursor
XDelete character before cursor
dDelete some text
cChange some text
yCopy (yank) some text

The <?> after each command represents the movement command used, for example:

  • dw — Delete one word after the cursor.
  • db — Delete one word before the cursor.
  • dd — Delete the entire current line.
  • c$ — Change from the current character to the end of the line (deletes then enters Input Mode).
  • c0 — Change from the character before the cursor to the start of the line.
  • cl — Delete current character and enter Input Mode.
  • cc — Delete current line and enter Input Mode.
  • yy — Copy the current line to the buffer.
  • y) — Copy the sentence to the right of the cursor to the buffer.
  • y} — Copy the paragraph to the right of the cursor to the buffer.

You can also use numbers to modify these commands:

  • 3dd — Delete 3 lines starting from the current line.
  • 3dw — Delete the next 3 words.
  • 5cl — Change the next 5 characters.
  • 12j — Move down 12 lines.
  • 5cw — Delete the next 5 words and enter Input Mode.
  • 4y) — Copy the next 4 sentences.
  1. Pasting (Placing) Text

Place the last text stored in the buffer into the file.

CommandDescription
PPaste to the left of the cursor; if a full line, paste above.
pPaste to the right of the cursor; if a full line, paste below.
  1. Repeating Commands

After deleting, changing, or pasting text, use . to repeat the action. For example, after replacing “Joe” with “Jim” (cw), find the next occurrence and press . to repeat the change.

  1. Exiting vi

In Command Mode, use ZZ to save and exit. Alternatively, press : to enter Ex Mode.

CommandDescription
:wSave the current file without exiting.
:wqSave and exit (same as ZZ).
:qExit, but only works if no changes were made.
:q!Force exit without saving changes.
  1. Other Commands
  • u — Undo changes.
  • Ctrl+R — Redo (undoes the previous undo).
  • :!command – Run a shell command directly after :!, e.g., :!date to see the current date. You can even use :!bash to start a new shell, but it’s better to save your work first.
  • Ctrl+g — Displays the filename, current line number, total lines, percentage of file content, and current column.

5.1.2 Navigating Through Files

If the file is long, use these methods to move faster:

CommandDescription
Ctrl+fPage forward one full screen.
Ctrl+bPage backward one full screen.
Ctrl+dScroll forward half a screen.
Ctrl+uScroll backward half a screen.
GGo to the last line of the file.
nGGo to line n.

5.1.3 Searching Text

Search forward or backward using / and ?. You can also use metacharacters:

  • /hello* — Search forward for lines starting with “hello”.
  • ?[pP]rint — Search backward for “print” or “Print”.

After starting a search, use n or N to search in the same or opposite direction.

5.1.4 Using Ex Mode

The vi editor was originally based on the ex editor. While it doesn’t work in full-screen mode, you can use Ex Mode commands to find and change text on one or more lines.

Enter Ex Mode from Command Mode using ::

  • :g/Local — Search for the word “Local” and print the relevant lines.
  • :s/Local/Remote — Replace the first occurrence of “Local” with “Remote” on the current line.
  • :g/Local/s//Remote — Replace the first “Local” on every line with “Remote”.
  • :g/Local/s//Remote/g — Replace every “Local” in the file with “Remote”.
  • :g/Local/s//Remote/gp — Replace every “Local” in the file and print each affected line.

5.1.5 Learning More

Run vimtutor to open a built-in tutorial in the vim editor.

5.2 Finding Files

Use these commands to help locate files on your system:

  • locate — Find files by name.
  • find — Find files based on various attributes.
  • grep — Search for specific text inside files.

5.2.1 Using locate to Find Files by Name

Most Linux systems run the updatedb command daily to index filenames into a database. The locate command searches this database. You can manually update it with sudo updatedb. You can only see files that your user has permission to access via locate.

locate [str] or locate -i [str] to ignore case. For example, to search for directories containing “yexca” regardless of case: locate -i yexca.

Note: Not all files are indexed; the /etc/updatedb.conf file determines which files are excluded from the database.

5.2.2 Using find to Search for Files

find is the most powerful command for searching the filesystem. It can find files based on attributes (metadata) and perform actions on the results.

Note: File metadata includes owner, group, timestamps, size, permissions, and other info stored in the inode.

find vs locate

find searches the actual filesystem, so it’s slower than locate, but it provides real-time results (whereas locate might miss new files). When using find, specify a starting point to limit the scope and improve speed.

The find command has a special -ls option that lists detailed file info, similar to ls -l.

Note: Regular users will see many errors due to permissions. You can redirect errors to /dev/null by adding 2>/dev/null to the end of the command.

  1. Finding files by name

Use -name and -iname (case-insensitive) for filenames. You can use wildcards (* and ?):

1
find /etc -iname '*passwd*'

This searches /etc for files containing “passwd” (case-insensitive). If no directory is specified, it searches the current folder.

Use the -type option to filter by files (-type f) or directories (-type d).

  1. Finding files by size

Use the -size option with + or - prefixes. For example, find /etc -size +10M finds files in /etc larger than 10MB.

1
find /bigdata -size +500M -size -5G -exec du -sh {} \;

This finds files between 500MB and 5GB in /bigdata and runs du on each to show their size.

  1. Finding files by user

Use -user or -group. You can combine these with -not and -or.

1
find /home \( -user yexca -or -user lemon \) -ls

Finds files in /home owned by either yexca or lemon.

  1. Finding files by permissions

Use the -perm option with numeric or symbolic modes.

  • -perm -777: Matches if at least all three bits are set.
  • -perm /777 (or +777 in older versions): Matches if any of the bits are set.
  • -perm 777: Exact match.

find -perm /002 finds files that are writable by “others,” regardless of other permissions.

  1. Finding files by date and time

Time options (-atime, -ctime, -mtime) search based on days since access, change, or metadata modification. Minute options (-amin, -cmin, -mmin) do the same for minutes.

Prefix the value with - for “less than” (from now until then) and + for “more than” (further back in time).

  • Changes in the last 10 minutes:
1
find /etc -mmin -10
  • Permission changes in the last three days:
1
find /bin /usr/bin -ctime -3
  • Files not accessed for over 300 days:
1
find /var/www -atime +300
  1. Using ’not’ and ‘or’ logic
  • Owned by yexca but not in the yexca group:
1
find /home -user yexca -not -group yexca -ls
  • Owned by yexca AND larger than 1GB:
1
find /home -user yexca -and -size +1G -ls
  1. Executing commands on found files

Use -exec to run a command on every match without confirmation, or -ok to ask for confirmation first. The syntax is:

1
2
find [options] -exec command {} \;
find [options] -ok command {} \;

{} represents the found filename. The command must end with \;.

1
find /etc -iname passwd -exec echo "I found {}" \;

5.2.3 Using grep to Search Inside Files

grep searches for specific text strings within files. It can print the matching lines or just the filenames. grep also works with standard output.

OptionDescription
-iIgnore case.
-vSearch for lines NOT containing the text.
-rSearch directories recursively.
-lShow only the names of matching files.
–colorHighlight the matching text (usually in red).
  • Recursively search for “root” in /etc/sysconfig:
1
grep -ri --color root /etc/sysconfig/
  • Search for “inet” in the output of a command:
1
ip addr show | grep inet