Skip to content

Instantly share code, notes, and snippets.

@nateberkopec
Last active March 10, 2026 23:18
Show Gist options
  • Select an option

  • Save nateberkopec/4d331d0ac786d57ec7e83cf52db7d72e to your computer and use it in GitHub Desktop.

Select an option

Save nateberkopec/4d331d0ac786d57ec7e83cf52db7d72e to your computer and use it in GitHub Desktop.
Update all .png references to .jpg across a codebase using git status pairs
#!/bin/bash
# After converting PNGs to JPEGs, update all references in the codebase.
# Parses git status for deleted .png / new .jpg pairs and does a global find-and-replace.
# Usage: ./rename_png_refs.sh [directory]
set -euo pipefail
DIR="${1:-.}"
DRY_RUN="${DRY_RUN:-false}"
# Get deleted .png bases (path without extension)
deleted_pngs=$(git status --porcelain | grep -E '^.D .*\.png$|^D .*\.png$' | sed 's/^.\{3\}//' | sed 's/\.png$//' | sort)
# Get new .jpg bases
new_jpgs=$(git status --porcelain | grep -E '^\?\? .*\.jpg$|^A. .*\.jpg$' | sed 's/^.\{3\}//' | sed 's/\.jpg$//' | sort)
# Find common bases (the matched pairs)
pairs=$(comm -12 <(echo "$deleted_pngs") <(echo "$new_jpgs"))
if [ -z "$pairs" ]; then
echo "No matching deleted .png / new .jpg pairs found in git status."
exit 0
fi
num_pairs=$(echo "$pairs" | wc -l | tr -d ' ')
echo "Found ${num_pairs} png->jpg pairs to rename across codebase:"
echo ""
count=0
while IFS= read -r base; do
[ -z "$base" ] && continue
filename=$(basename "$base")
old_ref="${filename}.png"
new_ref="${filename}.jpg"
hits=$(grep -rl --include='*.rb' --include='*.erb' --include='*.haml' --include='*.slim' \
--include='*.html' --include='*.css' --include='*.scss' --include='*.sass' \
--include='*.js' --include='*.ts' --include='*.tsx' --include='*.jsx' \
--include='*.yml' --include='*.yaml' --include='*.json' --include='*.md' \
"$old_ref" "$DIR" 2>/dev/null || true)
if [ -z "$hits" ]; then
echo " $old_ref -> $new_ref (no references found)"
count=$((count + 1))
continue
fi
num_files=$(echo "$hits" | wc -l | tr -d ' ')
if [ "$DRY_RUN" = "true" ]; then
echo " [dry-run] $old_ref -> $new_ref (${num_files} files)"
echo "$hits" | sed 's/^/ /'
else
echo "$hits" | while IFS= read -r f; do
sed -i '' "s|${old_ref}|${new_ref}|g" "$f"
done
echo " $old_ref -> $new_ref (${num_files} files updated)"
fi
count=$((count + 1))
done <<< "$pairs"
echo ""
echo "Done: ${count} replacements processed."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment