📁 Lesson 2.3: Working with Files and Directories
Create, copy, move, rename, and delete — the essential file operations.
🎯 Learning Objectives
- Create files with
touchand directories withmkdir - Copy files and directories with
cp - Move and rename with
mv - Delete files with
rmand directories withrmdir - Use wildcards to work with multiple files at once
- Find files with
findandlocate
Estimated Time: 45 minutes
📑 In This Lesson
Creating Files
touch — Create an Empty File
The simplest way to create a new, empty file:
# Create a single file
touch notes.txt
# Create multiple files at once
touch file1.txt file2.txt file3.txt
# Verify they exist
ls -l notes.txt file1.txt file2.txt file3.txt
💡 What touch Really Does
Technically, touch updates a file's timestamp. If the file doesn't exist, it creates an empty one as a side effect. If the file already exists, touch updates its "last modified" time without changing its contents.
Creating Files with Content
You can create files with content using redirection:
# Create a file with one line of text
echo "Hello, Linux!" > greeting.txt
# View the contents
cat greeting.txt
# Output: Hello, Linux!
# Append more text (>> adds to the end, > overwrites)
echo "This is a second line." >> greeting.txt
cat greeting.txt
# Output:
# Hello, Linux!
# This is a second line.
🔴 > vs >> — Know the Difference!
> overwrites the file — any existing content is destroyed. >> appends to the end. This is one of the most common mistakes beginners make. When in doubt, use >>.
contains: Hi"] C["echo 'Bye' >> file.txt"] -->|Appends| D["file.txt
contains: Hi
Bye"] style A fill:#ef4444,stroke:#b91c1c,color:#fff style C fill:#22c55e,stroke:#166534,color:#fff
Creating Directories
mkdir — Make Directory
# Create a single directory
mkdir projects
# Create multiple directories
mkdir photos videos music
# Create nested directories (parent + child in one command)
mkdir -p projects/website/css
# The -p flag creates all necessary parent directories
# Without -p, this would fail if "projects" or "website" didn't exist
✅ Always Use mkdir -p
The -p (parents) flag is your friend. It creates the full path of directories and doesn't complain if they already exist. There's almost no reason to use mkdir without it.
# Create a project structure in one shot
mkdir -p myproject/{src,tests,docs,assets/{images,fonts}}
# See what we built
tree myproject
Output:
myproject
├── assets
│ ├── fonts
│ └── images
├── docs
├── src
└── tests
6 directories, 0 files
💡 Brace Expansion
The {src,tests,docs} syntax is called brace expansion. Bash expands it into multiple arguments: myproject/src myproject/tests myproject/docs. You can use this with any command, not just mkdir.
Copying Files and Directories
cp — Copy
# Copy a file
cp notes.txt notes_backup.txt
# Copy a file to another directory
cp notes.txt ~/Documents/
# Copy a file to another directory with a new name
cp notes.txt ~/Documents/my_notes.txt
# Copy multiple files to a directory
cp file1.txt file2.txt file3.txt ~/Documents/
Copying Directories
To copy a directory and everything inside it, you need the -r (recursive) flag:
# Copy an entire directory
cp -r projects projects_backup
# -r means "recursive" — it copies the directory and all its contents
# Without -r, cp refuses to copy directories
| Option | Meaning |
|---|---|
-r |
Recursive — copy directories and their contents |
-i |
Interactive — ask before overwriting |
-v |
Verbose — show what's being copied |
-u |
Update — only copy if source is newer |
# A safe, verbose recursive copy
cp -riv projects projects_backup
Moving and Renaming
mv — Move (and Rename)
In Linux, moving and renaming are the same operation:
# Rename a file (move it to a new name in the same directory)
mv notes.txt my_notes.txt
# Move a file to another directory
mv my_notes.txt ~/Documents/
# Move and rename at the same time
mv my_notes.txt ~/Documents/important_notes.txt
# Move a directory (no -r needed, unlike cp)
mv projects ~/Documents/projects
# Move multiple files to a directory
mv file1.txt file2.txt file3.txt ~/Documents/
⚠️ mv Overwrites Silently
If the destination file already exists, mv will overwrite it without asking. Use mv -i (interactive) to get a confirmation prompt, or mv -n (no-clobber) to prevent overwriting entirely.
Deleting Files and Directories
🔴 There Is No Trash Can
In the Linux terminal, delete means delete. There is no Recycle Bin (Windows), no Trash (macOS), no undo, no "are you sure?" (unless you add the -i flag). Once a file is removed with rm, it's gone. Always double-check before pressing Enter.
rm — Remove Files
# Delete a single file
rm notes.txt
# Delete with confirmation prompt
rm -i notes.txt
# Output: rm: remove regular file 'notes.txt'? y
# Delete multiple files
rm file1.txt file2.txt file3.txt
# Delete all .txt files in the current directory
rm *.txt
rm -r — Remove Directories
# Remove a directory and everything inside it
rm -r old_project
# Remove with confirmation for each file
rm -ri old_project
# Force remove (no prompts, even for read-only files)
rm -rf old_project
🔴 The rm -rf Warning
rm -rf is the most dangerous command in Linux. It recursively force-deletes everything you point it at with no confirmation. Never run rm -rf / or rm -rf ~. Always double-check the path before using -rf. A typo can wipe your entire system.
rmdir — Remove Empty Directories
# Only works if the directory is empty
rmdir empty_folder
# Fails if the directory contains anything
rmdir projects
# Output: rmdir: failed to remove 'projects': Directory not empty
✅ Safe Deletion Habits
- Use
rm -iuntil you're confident (the-iflag asks before each delete) - Run
lsfirst to see what you're about to delete - Use
rm -rifor directories so you confirm each file - Consider adding
alias rm='rm -i'to your.bashrcfor permanent safety
Wildcards
Wildcards (also called globs) let you match multiple files with a pattern:
| Wildcard | Matches | Example | Matches These |
|---|---|---|---|
* |
Zero or more characters | *.txt |
notes.txt, readme.txt, .txt |
? |
Exactly one character | file?.txt |
file1.txt, fileA.txt, not file12.txt |
[abc] |
One character from the set | file[123].txt |
file1.txt, file2.txt, file3.txt |
[0-9] |
One character from the range | log[0-9].txt |
log0.txt through log9.txt |
# List all HTML files
ls *.html
# Copy all images to a backup
cp *.jpg *.png ~/backup/
# Move all files starting with "report"
mv report* ~/Documents/
# Delete all .tmp files
rm *.tmp
# List files with exactly 3-character extensions
ls *.???
💡 Test Before You Delete
Before running rm *.something, first run ls *.something to see which files match. This simple habit prevents accidental deletions.
Finding Files
When you need to find a file but don't know exactly where it is:
find — Search by Criteria
# Find files by name (starting from current directory)
find . -name "notes.txt"
# Find all .txt files under your home directory
find ~ -name "*.txt"
# Find files by name (case-insensitive)
find ~ -iname "readme*"
# Find only directories with a name
find /etc -type d -name "apt"
# Find only files (not directories)
find ~ -type f -name "*.log"
# Find files larger than 100MB
find / -type f -size +100M 2>/dev/null
# Find files modified in the last 7 days
find ~ -type f -mtime -7
💡 The 2>/dev/null Trick
When searching system directories, you'll see "Permission denied" errors for directories you can't read. Adding 2>/dev/null hides those errors by redirecting them to a virtual trash can. We'll cover redirection in more detail in Module 8.
locate — Fast Search by Name
The locate command uses a pre-built database and is much faster than find:
# Install locate
sudo apt install mlocate -y
# Update the database (run this first, and after adding new files)
sudo updatedb
# Search for a file
locate notes.txt
# Case-insensitive search
locate -i readme
🐧 find vs locate
find searches the live filesystem in real-time — always accurate but slower. locate searches a cached database — lightning fast but might miss recently created files. Use sudo updatedb to refresh locate's database.
🍎 On macOS
The find command works the same way on macOS. Instead of locate, macOS has mdfind, which uses the Spotlight index: mdfind notes.txt. It's fast and always up to date. You can also install locate via Homebrew if you prefer the Linux version.
which and type — Find Commands
# Where is a command located?
which ls
# Output: /usr/bin/ls
which python3
# Output: /usr/bin/python3
# More detailed info about a command
type ls
# Output: ls is aliased to 'ls --color=auto'
type cd
# Output: cd is a shell builtin
Exercises
🏋️ Exercise 1: Build a Project
Create the following structure using mkdir -p and touch:
my_website/
├── index.html
├── about.html
├── css/
│ └── style.css
├── js/
│ └── app.js
└── images/
💡 Solution
mkdir -p my_website/{css,js,images}
touch my_website/index.html
touch my_website/about.html
touch my_website/css/style.css
touch my_website/js/app.js
# Verify
tree my_website
🏋️ Exercise 2: Copy and Move
- Create a file:
echo "Important data" > data.txt - Copy it:
cp data.txt data_backup.txt - Create a directory:
mkdir archive - Move the backup:
mv data_backup.txt archive/ - Rename the original:
mv data.txt info.txt - Verify everything:
ls -laandls archive/
💡 Expected Result
You should have info.txt in the current directory and data_backup.txt inside the archive/ folder.
🏋️ Exercise 3: Wildcards Practice
Set up some test files, then use wildcards:
# Create test files
touch report_jan.txt report_feb.txt report_mar.txt
touch photo1.jpg photo2.jpg photo3.png
touch notes.md readme.md
# Now try:
ls *.txt # All text files
ls report* # All reports
ls photo?.jpg # Photos 1-9 (single digit)
ls *.md # All markdown files
# Move all reports to a folder
mkdir reports
mv report_*.txt reports/
# Verify
ls reports/
🏋️ Exercise 4: Find Things
# Find all .txt files in your home directory
find ~ -name "*.txt" -type f 2>/dev/null
# Find where the "bash" command lives
which bash
# Find all directories named "Documents" under /home
find /home -type d -name "Documents" 2>/dev/null
🏋️ Exercise 5: Clean Up
Remove the test files and directories you created:
# First, see what's there
ls
# Remove files
rm photo*.jpg photo*.png notes.md readme.md info.txt
# Remove directories
rm -r my_website reports archive
# Verify it's clean
ls
💡 Tip
Always run ls before rm to confirm what you're deleting. Especially when using wildcards — one wrong character can delete the wrong files.
Knowledge Check
❓ Question 1
What's the difference between > and >>?
❓ Question 2
Which command copies a directory and all its contents?
❓ Question 3
What does the wildcard *.txt match?
❓ Question 4
You accidentally typed rm important_file.txt and pressed Enter. Can you undo it?
Quick Reference
| Command | What It Does | Example |
|---|---|---|
touch |
Create an empty file | touch file.txt |
mkdir -p |
Create directories (including parents) | mkdir -p a/b/c |
cp |
Copy a file | cp src.txt dest.txt |
cp -r |
Copy a directory recursively | cp -r mydir backup |
mv |
Move or rename | mv old.txt new.txt |
rm |
Delete a file | rm file.txt |
rm -r |
Delete a directory and contents | rm -r old_dir |
find |
Search for files by criteria | find ~ -name "*.txt" |
which |
Find where a command lives | which python3 |
Summary
🎉 Key Takeaways
touchcreates empty files;echo "text" > filecreates files with contentmkdir -pcreates directories (and any missing parents)cpcopies files;cp -rcopies directoriesmvmoves and renames; it works on both files and directoriesrmdeletes permanently — there is no undo! Use-ifor safety>overwrites,>>appends — know the difference- Wildcards (
*,?,[]) let you work with multiple files at once findsearches in real-time;locateuses a cached database
🎉 Module 2 Complete!
You can now open the terminal, navigate the filesystem, and manage files and directories. These are the foundational skills for everything else in Linux.
🚀 What's Next?
In Module 3, you'll learn how Linux controls who can access what — users, groups, and the powerful permission system that keeps everything secure.