New version of sgit - many improvements

Now allows to not overwrite files.

Now allows sed options to be passed to sed.

Allows specifying path to sed.

This script now has its own repo at https://github.com/xexyl/sgit. I
don't expect many people to use it but it seemed like it was worthy of a
repo as it is a pretty handy script (though far from perfect).
This commit is contained in:
Cody Boone Ferguson committed 2023-02-15 09:08:40 -08:00
1 parent 1464a25e5a
commit af32e18f77
1 file changed
+73 -16
+73 -16
View File
@@ -16,22 +16,32 @@
# - Cody Boone Ferguson (@xexyl)
#
export SGIT_VERSION="0.0.2-1 13-02-2023" # format: major.minor.patch-release DD-MM-YYYY
export SGIT_VERSION="0.0.4-1 15-02-2023" # format: major.minor.patch-release DD-MM-YYYY
USAGE="usage: $(basename "$0") [-h] [-V] [-v level] [-x] [-e command] <glob...>
USAGE="usage: $(basename "$0") [-h] [-V] [-v level] [-x] [-I] [-o sed_options] [-s sed] [-e command] <glob...>
-h print help and exit
-V print version and exit
-x turn on tracing (set -x)
-v level set verbosity level
-x turn on tracing (set -x)
-I disable in place editing
-o sed options (don't pass '-')
-s sed set path to sed
-e command append sed command to execute on globs
sgit version: $SGIT_VERSION"
SED="$(type -P sed)"
export SED
export SED_OPTIONS=""
export I_FLAG=
export VERBOSITY=0
# we need an array for sed commands
declare -a SED_COMMANDS
# parse args
#
while getopts :hVxv:e: flag; do
while getopts :hVv:xIo:s:e: flag; do
case "$flag" in
h) echo "$USAGE" 1>&2
exit 2
@@ -39,9 +49,15 @@ while getopts :hVxv:e: flag; do
V) echo "$SGIT_VERSION" 1>&2
exit 2
;;
v) VERBOSITY="$OPTARG";
;;
x) set -x
;;
v) VERBOSITY="$OPTARG";
I) I_FLAG="-I"
;;
o) SED_OPTIONS="-$OPTARG"
;;
s) SED="$OPTARG"
;;
e) SED_COMMANDS+=(-e "$OPTARG")
;;
@@ -67,6 +83,25 @@ if [[ -z "${SED_COMMANDS[*]}" ]]; then
exit 2
fi
# check that sed is executable
if [[ -z "$SED" ]]; then
echo "$(basename "$0"): ERROR: sed cannot be empty" 1>&2
echo 1>&2
echo "$USAGE" 1>&2
exit 2
elif [[ ! -f "$SED" ]]; then
echo "$(basename "$0"): ERROR: sed is not a regular file: $SED" 1>&2
echo 1>&2
echo "$USAGE" 1>&2
exit 2
elif [[ ! -x "$SED" ]]; then
echo "$(basename "$0"): ERROR: sed is not an executable file: $SED" 1>&2
echo 1>&2
echo "$USAGE" 1>&2
exit 2
fi
# also check number of remaining args
if [[ "$#" -eq 0 ]]; then
echo "$(basename "$0"): ERROR: you must specify at least one glob" 1>&2
@@ -84,14 +119,14 @@ if [[ "$status" -ne 0 ]]; then
fi
if [[ $VERBOSITY -gt 1 ]]; then
echo "debug[2]: sed commands: ${SED_COMMANDS}[*]" 1>&2
echo "debug[2]: sed commands: ${SED_COMMANDS[*]}" 1>&2
fi
# This is not the best performance because it does this on all files of the glob
# rather than only those files matched by the glob with matching text but it's
# better than it used to be (it used to run git ls-files on the repo for each
# sed command so the more you had the slow it would become as it had to get the
# list of files each time!).
# This might not the best performance because it does this on all files of the
# glob rather than only those files matched by the glob with matching text but
# it's better than it used to be (it used to run git ls-files on the repo for
# each sed command so the more you had the slow it would become as it had to get
# the list of files each time!).
#
# A better approach would be to somehow use git grep to find files that match
# but this would complicate the command line (at least in anyway I can think of
@@ -110,12 +145,34 @@ while [[ "$i" -le "$#" ]]; do
echo "debug[2]: found glob: $1" 1>&2
fi
if [[ "$VERBOSITY" -ge 1 ]]; then
echo "debug[1]: about to run: git ls-files $1 | xargs sed -i\"\" ${SED_COMMANDS[*]}" 1>&2
if [[ -z "$I_FLAG" ]]; then
if [[ -n "$SED_OPTIONS" ]]; then
echo "debug[1]: about to run: git ls-files $1 | xargs $SED -i\"\" $SED_OPTIONS ${SED_COMMANDS[*]}" 1>&2
else
echo "debug[1]: about to run: git ls-files $1 | xargs $SED -i\"\" ${SED_COMMANDS[*]}" 1>&2
fi
else
if [[ -n "$SED_OPTIONS" ]]; then
echo "debug[1]: about to run: git ls-files $1 | xargs $SED $SED_OPTIONS ${SED_COMMANDS[*]}" 1>&2
else
echo "debug[1]: about to run: git ls-files $1 | xargs $SED ${SED_COMMANDS[*]}" 1>&2
fi
fi
fi
if [[ -z "$I_FLAG" ]]; then
if [[ -n "$SED_OPTIONS" ]]; then
git ls-files "$1" | xargs "$SED" -i"" "$SED_OPTIONS" "${SED_COMMANDS[*]}"
else
git ls-files "$1" | xargs "$SED" -i"" "${SED_COMMANDS[*]}"
fi
else
if [[ -n "$SED_OPTIONS" ]]; then
git ls-files "$1" | xargs "$SED" "$SED_OPTIONS" "${SED_COMMANDS[*]}"
else
git ls-files "$1" | xargs "$SED" "${SED_COMMANDS[*]}"
fi
fi
# shellcheck disable=SC2086
# SC2086 (info): Double quote to prevent globbing and word splitting. We can't
# quote this because we need to have word splitting.
git ls-files "$1" | xargs sed -i"" "${SED_COMMANDS[@]}"
((i++))
shift 1
done