Skip to content

Instantly share code, notes, and snippets.

@pvdb
Last active March 11, 2023 09:29
Show Gist options
  • Save pvdb/219ff69fdc2ee26dba1b45addaa9b96d to your computer and use it in GitHub Desktop.
Save pvdb/219ff69fdc2ee26dba1b45addaa9b96d to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
#
# INSTALLATION
#
# ln -s ${PWD}/subst $(brew --prefix)/bin/
# sudo ln -s ${PWD}/subst /usr/local/bin/
#
# ALTERNATIVE IMPLEMENTATION
#
# perl -p -i -e 's/${1?}/${2?}/g' file1.txt file2.txt ...
#
# NOTE: perl - behind the scenes - will create backup
# files, unlike the following ed-based implementation
# which carries out the substitution 'in situ'... as
# an additional bonus, it doesn't touch the timestamp
# of the files it processes if no substitution occurs
#
FROM="$1" ; shift ; # exclude ${FROM} from [<file>...] list
TO="$2" ; shift ; # exclude ${TO} from [<file>...] list
[ -z "${FROM}" ] || [ -z "${TO}" ] && { # check command-line options
>&2 echo 'Usage: subst <from> <to> [<file>...]' ;
exit 1 ;
}
DELIM=$'\a' ; # use 'BEL' as delimiter in ed addresses and commands
MATCH="g${DELIM}${FROM}${DELIM}" ; # g/<from>/
SUBST="s${DELIM}${FROM}${DELIM}${TO}${DELIM}g" ; # s/<from>/<to>/g
for FILE ; do
# this grep is required to prevent subst from
# changing the timestamp of files that DO NOT
# contain the string we want to substitute!!!
if grep --quiet -- "${FROM}" "${FILE}" ; then
# now do the actual substitution using ed
# but only if the ${FROM} string actually
# occurs on the line: suppress ed warning
# when saving the subst file back to disk
echo "${MATCH}${SUBST}
w
q" | ed -s "${FILE}" ;
fi
done
# That's all Folks!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment