File Manipulation
File manipulation is at the heart of shell scripting. Whether you're organizing files, setting permissions, or finding specific files, Bash provides powerful commands for every task. In this lesson, you'll master cp, mv, rm, chmod, and the incredibly versatile find command!
Basic File Operations: cp, mv, rm
The fundamental file manipulation commands let you copy, move, rename, and delete files and directories.
Click Run to execute your code
| Command | Description | Common Options |
|---|---|---|
cp |
Copy files/directories | -r (recursive), -p (preserve), -i (interactive) |
mv |
Move or rename files | -i (interactive), -n (no overwrite) |
rm |
Remove files/directories | -r (recursive), -f (force), -i (interactive) |
touch |
Create file / update timestamp | -t (set time), -d (date string) |
mkdir |
Create directories | -p (create parents) |
rmdir |
Remove empty directories | -p (remove parents) |
rm -rf is extremely dangerous! It recursively deletes without confirmation. Never run rm -rf / or rm -rf * with elevated privileges. Always double-check paths before using -rf.
File Permissions with chmod
Unix file permissions control who can read, write, and execute files. The chmod command lets you modify these permissions.
Click Run to execute your code
Understanding Permission Numbers
| Permission | Letter | Number | Meaning |
|---|---|---|---|
| Read | r | 4 | View file contents / list directory |
| Write | w | 2 | Modify file / add/remove files in directory |
| Execute | x | 1 | Run as program / enter directory |
755- Executables (owner: full, others: read+execute)644- Regular files (owner: read+write, others: read)700- Private files (owner only)600- Sensitive files like SSH keys
chmod u+x script.sh (add execute for user), chmod go-w file (remove write for group/others), chmod a+r file (add read for all).
Finding Files with find
The find command is incredibly powerful for locating files based on name, type, size, time, permissions, and more.
Click Run to execute your code
Essential find Options
# Find by name
find /path -name "*.txt" # Case-sensitive
find /path -iname "*.TXT" # Case-insensitive
# Find by type
find /path -type f # Files only
find /path -type d # Directories only
find /path -type l # Symbolic links
# Find by time
find /path -mtime -7 # Modified within 7 days
find /path -mtime +30 # Modified more than 30 days ago
find /path -mmin -60 # Modified within 60 minutes
# Find by size
find /path -size +100M # Larger than 100MB
find /path -size -1k # Smaller than 1KB
# Find by permissions
find /path -perm 755 # Exact permissions
find /path -perm -u+x # At least user executable
# Execute command on results
find /path -name "*.log" -delete # Delete matching files
find /path -name "*.sh" -exec chmod +x {} \; # Make executable
find /path -type f -exec grep -l "pattern" {} \; # Search in files
xargs:
find /path -name "*.txt" | xargs grep "pattern"
find /path -name "*.log" -print0 | xargs -0 rm -f # Handle spaces in names
Common Mistakes
1. Forgetting -r for directories
# Wrong - can't copy directory without -r
cp mydir newdir # Error!
# Correct
cp -r mydir newdir
2. Dangerous rm patterns
# EXTREMELY DANGEROUS!
rm -rf / # Deletes everything
rm -rf $VAR/* # If VAR is empty, becomes rm -rf /*
# Safer patterns
rm -rf "${VAR:?Error: VAR not set}/"* # Fails if VAR is empty
[[ -n "$VAR" ]] && rm -rf "$VAR"/*
3. Wrong chmod numbers
# Wrong - gives everyone write access
chmod 777 sensitive_file.txt # DANGEROUS!
# Correct - restrictive permissions
chmod 600 sensitive_file.txt # Owner only
chmod 644 public_file.txt # Owner write, others read
4. Forgetting quotes with find
# Wrong - shell expands * before find sees it
find /path -name *.txt
# Correct - quotes prevent shell expansion
find /path -name "*.txt"
Exercise: File Organizer Script
Task: Create a script that organizes files by extension!
Requirements:
- Create directories for different file types (txt, log, sh)
- Move files to appropriate directories based on extension
- Set correct permissions (755 for scripts, 644 for others)
- Count files moved to each directory
Show Solution
#!/bin/bash
# File Organizer Script
source_dir="/tmp/organize_test"
mkdir -p "$source_dir"
# Create test files
touch "$source_dir"/{file1.txt,file2.txt,app.log,error.log,script.sh,deploy.sh}
echo "=== File Organizer ==="
echo "Source: $source_dir"
echo ""
# Create category directories
mkdir -p "$source_dir"/{text_files,log_files,scripts}
# Move and count files
txt_count=0
log_count=0
sh_count=0
# Move .txt files
for f in "$source_dir"/*.txt 2>/dev/null; do
[[ -f "$f" ]] || continue
mv "$f" "$source_dir/text_files/"
chmod 644 "$source_dir/text_files/$(basename "$f")"
((txt_count++))
done
# Move .log files
for f in "$source_dir"/*.log 2>/dev/null; do
[[ -f "$f" ]] || continue
mv "$f" "$source_dir/log_files/"
chmod 644 "$source_dir/log_files/$(basename "$f")"
((log_count++))
done
# Move .sh files
for f in "$source_dir"/*.sh 2>/dev/null; do
[[ -f "$f" ]] || continue
mv "$f" "$source_dir/scripts/"
chmod 755 "$source_dir/scripts/$(basename "$f")"
((sh_count++))
done
echo "Files organized:"
echo " Text files: $txt_count"
echo " Log files: $log_count"
echo " Scripts: $sh_count"
echo ""
echo "Directory structure:"
find "$source_dir" -type f
# Cleanup
rm -rf "$source_dir"
Summary
- cp: Copy files (
-rfor directories,-ppreserve attributes) - mv: Move or rename files and directories
- rm: Delete files (
-rfor directories, use-ifor safety) - chmod: Change permissions (numeric: 755, 644 or symbolic: u+x, go-w)
- find: Search files by name, type, time, size, permissions
- Safety: Always quote variables, double-check
rm -rfcommands
What's Next?
Now let's explore File Testing in more depth. You'll learn advanced techniques for checking file properties, comparing files, and making your scripts robust with proper file validation!
Enjoying these tutorials?