Last active
January 27, 2025 16:34
-
-
Save kitzberger/59a93e7136d006baa780f96607584501 to your computer and use it in GitHub Desktop.
Git Replace
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -------------------------------------------------------------------- | |
# 1st parameter: regex search string | |
# - if you wanna match brackets (, ), [, ] you need to escape them | |
# - otherwise they are handled as capture groups and character classes | |
# 2nd parameter: regex replace string (can be empty as well) | |
# - don't escape anything | |
# - back references to the first 3 capture groups can be used here: \1, \2 and \3 | |
# -------------------------------------------------------------------- | |
function gitreplace() { | |
if [ -z "$1" ]; then | |
echo "No pattern given!" | |
echo | |
echo "Examples:" | |
echo "gitreplace 'something old' 'nice and new'" | |
echo "gitreplace 'something really old' DROP/DROP+1/DROP+2/..." | |
echo "gitreplace 'old' 'new' <target>" | |
echo | |
echo "__BOL__ and __EOL__ can be used to match beginning and end of line!" | |
return | |
fi | |
search="$1" | |
replace="$2" | |
if [ -z "$3" ]; then | |
target="." | |
else | |
target="$3" | |
fi | |
# ----------------------- | |
# Escape search parameter | |
# ----------------------- | |
# Substitute escaped characters by temporary tokens | |
search="${search/\\\[/__SQUARE_OPEN__}" | |
search="${search/\\\]/__SQUARE_CLOSE__}" | |
search="${search/\\\(/__ROUND_OPEN__}" | |
search="${search/\\\)/__ROUND_CLOSE__}" | |
search="${search/\\\$/__DOLLAR__}" | |
search="${search/\\\./__DOT__}" | |
# Escape backslashes & slashes | |
search="${search//\\/\\\\}" | |
search="${search//\//\\/}" | |
# Re-substitute temporary tokens back to escape characters | |
search="${search/__SQUARE_OPEN__/\\\[}" | |
search="${search/__SQUARE_CLOSE__/\\\]}" | |
search="${search/__ROUND_OPEN__/\\\(}" | |
search="${search/__ROUND_CLOSE__/\\\)}" | |
search="${search/__DOLLAR__/\\\$}" | |
search="${search/__DOT__/\\\.}" | |
# Replace magic tokens | |
search="${search/__BOL__/\^}" | |
search="${search/__EOL__/\$}" | |
# -------------------------------------- | |
# Find matching text files of repository | |
# -------------------------------------- | |
# -l Instead of showing every matched line, show only the names of files that contain matches | |
# -I Don’t match the pattern in binary files | |
# -E extended regex | |
#echo git grep -l -I -E \""$search"\" -- "$target" | |
files=$(git grep -l -I -E "$search" -- "$target") | |
if [ -z "$files" ]; then | |
echo "No files found matching pattern '$search'!" | |
echo | |
echo "Hint: literal brackets have to be escaped!" | |
return | |
#else | |
# echo "Files: $files" | |
fi | |
# ------------------------ | |
# Escape replace parameter | |
# ------------------------ | |
# Substitute capture group back references by temporary tokens | |
replace="${replace//\\1/__REFERENCE_1__}" | |
replace="${replace//\\2/__REFERENCE_2__}" | |
replace="${replace//\\3/__REFERENCE_3__}" | |
# Escape backslashes & slashes | |
replace="${replace//\\/\\\\}" | |
replace="${replace//\//\\/}" | |
# Re-substitute temporary tokens back to capture group back references | |
replace="${replace//__REFERENCE_1__/\\1}" | |
replace="${replace//__REFERENCE_2__/\\2}" | |
replace="${replace//__REFERENCE_3__/\\3}" | |
# ----------------------- | |
# Perform the replacement | |
# ----------------------- | |
# -r extended regex | |
# Matching line should be simply dropped: | |
if [[ "$replace" == DROP* ]]; then | |
lines=${replace/DROP+/} | |
lines=$((lines)) # cast to integer | |
echo "$files" | while IFS= read -r file; do | |
sed -r -i "/$search/,+${lines}d" -- "$file" | |
done | |
else | |
echo "$files" | while IFS= read -r file; do | |
sed -r -i "s/$search/$replace/g" -- "$file" | |
done | |
fi | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment