File Handling in Bash

File handling is one of the most practical skills in Bash. Scripts constantly read from files, write to files, and check whether files exist. This topic covers everything needed to work with files confidently.

Checking if a File or Directory Exists

Before reading or writing a file, always check whether it exists. Use file test operators inside an if statement.

#!/bin/bash
if [ -f "report.txt" ]; then
  echo "File exists."
else
  echo "File not found."
fi
#!/bin/bash
if [ -d "backups" ]; then
  echo "Directory exists."
else
  echo "Directory does not exist."
fi

Creating a File

Using touch

touch newfile.txt

Using echo with Redirection

echo "First line of file" > notes.txt

Using cat with Redirection (Multi-line)

cat > greetings.txt <<EOF
Hello, welcome!
This is a multi-line file.
Created by Bash script.
EOF

Writing to a File

Overwrite a File (single >)

The > symbol overwrites the file with new content. Any existing content is removed.

#!/bin/bash
echo "This is new content." > output.txt

Append to a File (double >>)

The >> symbol adds new content at the end of the file without removing existing content.

#!/bin/bash
echo "First entry" > log.txt
echo "Second entry" >> log.txt
echo "Third entry" >> log.txt

After running, log.txt contains:

First entry
Second entry
Third entry

Redirection Diagram

┌──────────────────────────────────────────────────┐
│                                                  │
│  echo "text" > file.txt                          │
│  ────────────────────────────                    │
│  OVERWRITES file with "text"                     │
│                                                  │
│  echo "text" >> file.txt                         │
│  ────────────────────────────                    │
│  APPENDS "text" to end of file                   │
│                                                  │
│  command < file.txt                              │
│  ────────────────────────────                    │
│  Sends file content as INPUT to command          │
└──────────────────────────────────────────────────┘

Reading a File Line by Line

#!/bin/bash
while IFS= read -r line
do
  echo "$line"
done < students.txt

The IFS= prevents leading/trailing spaces from being trimmed. The -r flag prevents backslashes from being treated as escape characters.

Reading File Content into a Variable

#!/bin/bash
content=$(cat notes.txt)
echo "File content: $content"

Counting Lines, Words, and Characters in a File

#!/bin/bash
echo "Lines:      $(wc -l < report.txt)"
echo "Words:      $(wc -w < report.txt)"
echo "Characters: $(wc -c < report.txt)"

Searching Inside a File with grep

grep searches for a pattern inside a file and prints matching lines.

#!/bin/bash
grep "error" server.log

Case-insensitive search:

grep -i "error" server.log

Show line numbers with matches:

grep -n "error" server.log

Count the number of matching lines:

grep -c "error" server.log

Copying, Moving, and Deleting Files

#!/bin/bash
# Copy
cp report.txt report_backup.txt

# Move / Rename
mv report.txt /home/john/documents/

# Delete
rm old_report.txt

# Delete a directory and all its contents
rm -rf temp_folder/

File Permissions

Every file in Linux has three permission groups: owner, group, and others. Each group can have read (r), write (w), and execute (x) permissions.

┌──────────────────────────────────────────────────────┐
│  -rwxr-xr--                                          │
│   │││ │││ │││                                        │
│   │││ │││ └── Others: read only                      │
│   │││ └────── Group: read + execute                  │
│   └────────── Owner: read + write + execute          │ 
│   └─── File type: - = regular file, d = directory    │
└──────────────────────────────────────────────────────┘

chmod – Change Permissions

chmod 755 script.sh   # Owner: rwx, Group: r-x, Others: r-x
chmod 644 data.txt    # Owner: rw-, Group: r--, Others: r--
chmod +x script.sh    # Add execute permission for all

Numeric Permission Reference

NumberPermission
7read + write + execute (rwx)
6read + write (rw-)
5read + execute (r-x)
4read only (r--)
0no permission (---)

Practical Example – Log File Manager

#!/bin/bash
logfile="app.log"

log_message() {
  local timestamp
  timestamp=$(date "+%Y-%m-%d %H:%M:%S")
  echo "[$timestamp] $1" >> $logfile
}

log_message "Script started"
log_message "Processing data..."
log_message "Task complete"

echo "Log entries written to $logfile"
cat $logfile

Output:

Log entries written to app.log
[2026-04-18 10:00:01] Script started
[2026-04-18 10:00:01] Processing data...
[2026-04-18 10:00:01] Task complete

Key Takeaways

  • Use -f and -d to check if a file or directory exists before working with it.
  • Use > to overwrite a file and >> to append to it.
  • Use while IFS= read -r line to read a file line by line safely.
  • Use grep to search for patterns inside files.
  • Use chmod to control who can read, write, or execute a file.

Leave a Comment