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 deleteBash
#!/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