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) # - 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 -h print help and exit
-V print version and exit -V print version and exit
-x turn on tracing (set -x)
-v level set verbosity level -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 -e command append sed command to execute on globs
sgit version: $SGIT_VERSION" sgit version: $SGIT_VERSION"
SED="$(type -P sed)"
export SED
export SED_OPTIONS=""
export I_FLAG=
export VERBOSITY=0 export VERBOSITY=0
# we need an array for sed commands
declare -a SED_COMMANDS
# parse args # parse args
# #
while getopts :hVxv:e: flag; do while getopts :hVv:xIo:s:e: flag; do
case "$flag" in case "$flag" in
h) echo "$USAGE" 1>&2 h) echo "$USAGE" 1>&2
exit 2 exit 2
@@ -39,9 +49,15 @@ while getopts :hVxv:e: flag; do
V) echo "$SGIT_VERSION" 1>&2 V) echo "$SGIT_VERSION" 1>&2
exit 2 exit 2
;; ;;
v) VERBOSITY="$OPTARG";
;;
x) set -x x) set -x
;; ;;
v) VERBOSITY="$OPTARG"; I) I_FLAG="-I"
;;
o) SED_OPTIONS="-$OPTARG"
;;
s) SED="$OPTARG"
;; ;;
e) SED_COMMANDS+=(-e "$OPTARG") e) SED_COMMANDS+=(-e "$OPTARG")
;; ;;
@@ -67,6 +83,25 @@ if [[ -z "${SED_COMMANDS[*]}" ]]; then
exit 2 exit 2
fi 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 # also check number of remaining args
if [[ "$#" -eq 0 ]]; then if [[ "$#" -eq 0 ]]; then
echo "$(basename "$0"): ERROR: you must specify at least one glob" 1>&2 echo "$(basename "$0"): ERROR: you must specify at least one glob" 1>&2
@@ -84,14 +119,14 @@ if [[ "$status" -ne 0 ]]; then
fi fi
if [[ $VERBOSITY -gt 1 ]]; then if [[ $VERBOSITY -gt 1 ]]; then
echo "debug[2]: sed commands: ${SED_COMMANDS}[*]" 1>&2 echo "debug[2]: sed commands: ${SED_COMMANDS[*]}" 1>&2
fi fi
# This is not the best performance because it does this on all files of the glob # This might not the best performance because it does this on all files of the
# rather than only those files matched by the glob with matching text but it's # glob rather than only those files matched by the glob with matching text but
# better than it used to be (it used to run git ls-files on the repo for each # it's better than it used to be (it used to run git ls-files on the repo for
# sed command so the more you had the slow it would become as it had to get the # each sed command so the more you had the slow it would become as it had to get
# list of files each time!). # the list of files each time!).
# #
# A better approach would be to somehow use git grep to find files that match # 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 # 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 echo "debug[2]: found glob: $1" 1>&2
fi fi
if [[ "$VERBOSITY" -ge 1 ]]; then 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 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++)) ((i++))
shift 1 shift 1
done done