Bash File Operations - Create, Read, Delete, Copy, Move, Permissions
Quick Answer: Essential File Operations
Create files with touch name.txt or echo "content" > file.txt. Read with cat, head, tail, or while read. Copy with cp, move with mv, delete with rm. Check permissions with ls -l and change with chmod 755 file. Test file existence with [ -f "$file" ].
Quick Comparison: Common File Operations
| Operation | Command | Best For |
|---|---|---|
| Create empty | touch file.txt | Placeholder files |
| Create with content | echo "text" > file.txt | Quick file creation |
| Create multi-line | cat << EOF | Complex content |
| Read | cat file.txt | Simple viewing |
| Read line-by-line | while read | Processing |
| Copy | cp source dest | Duplicating files |
| Move/Rename | mv old new | Renaming and moving |
| Delete | rm file.txt | Removing files |
| Set permissions | chmod 644 file.txt | Securing files |
| Test existence | [ -f "$file" ] | Checking before use |
Bottom line: Master touch, cat, cp, mv, rm, chmod, and conditional tests—these cover 90% of daily file operations.
File operations are fundamental to system administration. This guide covers creating, reading, modifying, and managing files and permissions.
Table of Contents
- Creating Files
- Reading Files
- Modifying Files
- Copying and Moving
- File Permissions
- File Attributes
- File Testing
- Best Practices
- Frequently Asked Questions
Creating Files
File creation in Bash is straightforward, but understanding the different methods helps you choose the right tool for the job. Creating an empty placeholder file is different from creating a file with specific content, and both are different from creating temporary files that clean up automatically.
Create Empty File
The touch command creates an empty file if it doesn’t exist, or updates its modification time if it does. This is perfect for creating placeholder files or ensuring a file exists before you write to it.
touch newfile.txt
This creates newfile.txt with zero bytes. It’s commonly used to create files you’ll populate later, or to create a marker file that indicates something has happened (like a lock file).
Create with Content
The quickest way to create a file with content is to use echo and redirect the output to a file. The > operator creates the file and writes to it, replacing it if it already exists. Use >> to append instead of replacing.
echo "Hello, World!" > newfile.txt
This creates newfile.txt containing “Hello, World!” exactly. The > operator is fast and simple for single-line content. For multiple lines, use the here-document syntax below.
Create Multi-line File
For files with multiple lines, the cat command with a here-document (<< EOF ... EOF) is elegant and readable. Everything between << EOF and EOF becomes the file content:
cat > myfile.txt << EOF
Line 1
Line 2
Line 3
EOF
This is perfect for creating configuration files, scripts, or any content with multiple lines. The here-document preserves formatting and makes the content obvious in your script. Use << 'EOF' (with quotes) if you want to prevent variable expansion in the content.
Create Temporary File
Temporary files are essential for scripts that need to store intermediate data without cluttering the filesystem. The mktemp command creates a uniquely-named temporary file automatically:
# Create unique temporary file
tmpfile=$(mktemp)
echo "temp data" > "$tmpfile"
# Use temporary file
cat "$tmpfile"
# Clean up
rm "$tmpfile"
mktemp generates a filename like /tmp/tmp.XXXXXXXXXX that’s guaranteed to be unique. This prevents conflicts if your script runs multiple times simultaneously. Always clean up temporary files when you’re done with them.
When to Use Each File Creation Method
- touch: When you just need a placeholder or marker file
- echo >: For quick, single-line file creation
- cat << EOF: For multi-line files with stable content
- mktemp: When you need temporary storage in scripts
Reading Files
Display File Content
cat filename.txt
Display with Line Numbers
cat -n filename.txt
Display First/Last Lines
head -5 filename.txt # First 5 lines
tail -5 filename.txt # Last 5 lines
Read into Variable
content=$(cat filename.txt)
echo "$content"
Read Line by Line
while IFS= read -r line; do
echo "Line: $line"
done < filename.txt
Modifying Files
Append Content
echo "New line" >> existing.txt
Overwrite Content
echo "New content" > file.txt
Edit In-Place with sed
# Replace text
sed -i 's/old/new/g' file.txt
# Delete lines
sed -i '/pattern/d' file.txt
Prepend Line
# Add line at beginning
sed -i '1i New first line' file.txt
Copying and Moving
Copy File
cp source.txt destination.txt
Copy with Attributes
cp -p source.txt destination.txt
Copy Directory Recursively
cp -r source_dir destination_dir
Move/Rename File
mv oldname.txt newname.txt
mv file.txt /new/location/
Move Multiple Files
mv *.log /var/log/
File Permissions
View Permissions
ls -l filename.txt
# Output: -rw-r--r-- 1 user group 245 Feb 21 10:00 filename.txt
Understanding Permissions
-rw-r--r--
^ owner group others
rw- read/write
r-- read only
r-- read only
Change Permissions
# Make executable
chmod +x script.sh
# Remove write permission
chmod -w file.txt
# Set specific permissions
chmod 644 file.txt # rw-r--r--
chmod 755 script.sh # rwxr-xr-x
chmod 600 secret.txt # rw-------
Recursive Permissions
# Change directory and contents
chmod -R 755 /path/to/dir
Change Owner
sudo chown user:group filename.txt
sudo chown -R user:group /path/to/dir
File Attributes
View File Info
stat filename.txt # Detailed information
file filename.txt # File type
ls -li filename.txt # Inode and size
Set Immutable (Prevent Deletion)
sudo chattr +i important_file # Make immutable
sudo chattr -i important_file # Remove immutable
Compress File
gzip file.txt # Creates file.txt.gz
gunzip file.txt.gz # Extracts
File Testing
Test File Existence
if [ -f "$file" ]; then
echo "File exists"
fi
Test File Properties
[ -r "$file" ] # Readable
[ -w "$file" ] # Writable
[ -x "$file" ] # Executable
[ -s "$file" ] # Not empty
[ -d "$dir" ] # Directory
[ -L "$link" ] # Symbolic link
Test File Equality
if [ "$file1" -nt "$file2" ]; then
echo "file1 is newer"
fi
if [ "$file1" -ot "$file2" ]; then
echo "file1 is older"
fi
Best Practices
1. Quote File Names
# Good (handles spaces)
cp "$source" "$dest"
# Poor (fails with spaces)
cp $source $dest
2. Check Before Deletion
# Safe pattern
if [ -f "$file" ]; then
echo "Deleting: $file"
rm "$file"
else
echo "File not found"
fi
3. Use Absolute Paths
# Good
cp /home/user/file.txt /backup/
# Less clear
cp ./file.txt ../backup/
4. Preserve Attributes When Copying
# Preserves permissions, timestamps, ownership
cp -p source.txt destination.txt
5. Back Up Before Modifying
# Create backup before in-place editing
cp file.txt file.txt.bak
sed -i 's/old/new/g' file.txt
Practical Examples
Batch Rename Files
#!/bin/bash
# Rename all .txt to .backup
for file in *.txt; do
[ -f "$file" ] && mv "$file" "${file%.txt}.backup"
done
Find and Delete Old Files
# Find and delete files older than 30 days
find /var/log -name "*.log" -mtime +30 -delete
Archive and Compress
# Create tar.gz archive
tar -czf backup.tar.gz /home/user/documents
Secure File Deletion
# Overwrite before deleting (slower, more secure)
shred -vfz -n 3 secret_file.txt
Frequently Asked Questions
Q: How do I safely delete files?
A: Use rm -i for confirmation, or shred for secure deletion.
Q: What’s the difference between cp and rsync?
A: rsync is better for syncing directories; cp is simpler for single files.
Q: How do I move large files?
A: mv is fast (same filesystem); use rsync for remote moves.
Q: Can I undo file deletion?
A: No, use backups or recovery tools. Better to prevent deletion errors.
Next Steps
Explore related topics:
- Bash Complete Guide - File operations overview
- Bash Control Structures - Loop through files
- Bash Functions - Reusable file operation functions