From af32e18f779620592600afbaf1cd47511fbef0eb Mon Sep 17 00:00:00 2001 From: Cody Boone Ferguson <53008573+xexyl@users.noreply.github.com> Date: Wed, 15 Feb 2023 09:08:40 -0800 Subject: [PATCH] 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). --- bin/sgit | 89 ++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 73 insertions(+), 16 deletions(-) diff --git a/bin/sgit b/bin/sgit index c5ccb9f61..f6c72db25 100755 --- a/bin/sgit +++ b/bin/sgit @@ -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] +USAGE="usage: $(basename "$0") [-h] [-V] [-v level] [-x] [-I] [-o sed_options] [-s sed] [-e command] -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