ShBash · Lesson 5 of 8

Working with Files

Bash was born to manipulate files. Half the Unix philosophy is "everything is a file." The other half is "small tools that do one thing well."

Bash
#!/bin/bash

# Reading files
# cat — print entire file
cat file.txt

# Read line by line (best for processing)
while IFS= read -r line; do
    echo ">> $line"
done < "file.txt"

# head/tail
head -5 file.txt    # first 5 lines
tail -10 file.txt   # last 10 lines
tail -f log.txt     # follow a growing file (Ctrl+C to stop)

# Writing files
echo "Hello" > output.txt    # write (overwrites!)
echo "World" >> output.txt   # append
cat > multi.txt << 'EOF'
Line 1
Line 2
Line 3
EOF

# File operations
cp source.txt dest.txt          # copy
cp -r source_dir/ dest_dir/     # copy directory recursively
mv old_name.txt new_name.txt    # rename or move
rm file.txt                     # remove (no recycle bin!)
rm -rf directory/               # remove directory recursively (CAREFUL)

# Safe remove — always check before deleting
echo "Would remove: file.txt"   # dry run first
rm -i file.txt                  # interactive — asks for confirmation

# Find files
find . -name "*.sh" -type f           # find .sh files
find . -newer reference.txt           # files newer than reference
find . -size +1M                      # files larger than 1MB
find . -name "*.log" -delete          # find and delete
Bash
#!/bin/bash

# Text processing — the Unix triumvirate
# grep — search for patterns
grep "error" log.txt               # lines containing "error"
grep -i "error" log.txt            # case-insensitive
grep -r "TODO" ./src/              # recursive
grep -n "main" script.sh           # show line numbers
grep -v "debug" log.txt            # invert — lines WITHOUT "debug"
grep -c "error" log.txt            # count matching lines

# sed — stream editor (find and replace)
sed 's/foo/bar/g' file.txt         # replace all foo with bar
sed -i 's/foo/bar/g' file.txt      # replace in-place (modifies file!)
sed -i.bak 's/foo/bar/g' file.txt  # replace in-place, keep backup
sed '/^#/d' file.txt               # delete lines starting with #
sed -n '5,10p' file.txt            # print lines 5-10

# awk — pattern scanning and processing
awk '{print $1}' file.txt          # print first field (space-separated)
awk -F: '{print $1}' /etc/passwd   # use : as delimiter
awk '{sum += $1} END {print sum}' numbers.txt  # sum first column
awk 'NR > 1 {print}' file.txt      # skip header line

# Combining with pipes
grep "ERROR" log.txt | awk '{print $4}' | sort | uniq -c | sort -rn