New version of sgit

Now supports backup extension.

Some warnings are noted in the usage (about backup extensions - one of
which goes for sed in general) and the README.md file.

Typo fixed the README.md file (some examples were in error for instance)
as well and add additional examples.

The new version corresponds to
https://github.com/xexyl/sgit/commit/9fccaa8cd680d3ed7cd91516710a5672630b5dff;
the README.md file had several new commits.
This commit is contained in:
Cody Boone Ferguson committed 2023-04-19 03:15:29 -07:00
1 parent fae013b322
commit baf357a23f
2 files changed
+115 -34

No files matched your search

+27 -12
View File
@@ -5,28 +5,33 @@
#
# This script allows one to run sed under git control without having to come up
# with a list of files first and then passing those to the command.
#
# It allows for multiple sed commands and multiple globs. By default it uses -i
# to edit the file in place (without backup extension) but this can be
# overridden with the -I option. See -h option for all the options.
# to edit the file in place (WITHOUT BACKUP EXTENSION; use -i option if you want
# a backup!) but in place editing can be overridden with the -I option. See -h
# option for all the options.
#
# DISCLAIMER AND WARNING: this is something of a hack and might be error prone.
# It works for what is needed but possibly could be improved. Even so I like it
# how it is and I don't think it would do good to add any additional features
# except perhaps allowing for one to specify path to sed.
# how it is and I don't think it would do much good to add many more additional
# features.
#
# - Cody Boone Ferguson (@xexyl)
#
export SGIT_VERSION="0.0.7-1 12-04-2023" # format: major.minor.patch-release DD-MM-YYYY
export SGIT_VERSION="0.0.8-1 19-04-2023" # format: major.minor.patch-release DD-MM-YYYY
USAGE="usage: $(basename "$0") [-h] [-V] [-v level] [-x] [-I] [-o sed_options] [-s sed] [-e command] <glob...>
USAGE="usage: $(basename "$0") [-h] [-V] [-v level] [-x] [-I] [-i extension] [-o sed_options] [-s sed] [-e command] <glob...>
-h print help and exit
-V print version and exit
-v level set verbosity level
-x turn on tracing (set -x)
-I disable in place editing
-o sed options (don't pass '-')
-i extension set backup extension (default none)
WARNING: sed -i overwrites existing files
WARNING: this will create another file for each file changed
-o sed options (NOTE: don't pass '-'!)
WARNING: use of '-o n' without '-I', can depending on command, empty files
-s sed set path to sed
-e command append sed command to to list to execute on globs
@@ -38,6 +43,7 @@ export SED
export SED_OPTIONS=""
export I_FLAG=
export VERBOSITY=0
export EXTENSION=""
# we need an array for sed commands
declare -a SED_COMMANDS
@@ -47,7 +53,7 @@ IFS=$'\t\n'
# parse args
#
while getopts :hVv:xIo:s:e: flag; do
while getopts :hVv:xIi:o:s:e: flag; do
case "$flag" in
h) echo "$USAGE" 1>&2
exit 2
@@ -61,6 +67,8 @@ while getopts :hVv:xIo:s:e: flag; do
;;
I) I_FLAG="-I"
;;
i) EXTENSION="$OPTARG"
;;
o) SED_OPTIONS="-$OPTARG"
;;
s) SED="$OPTARG"
@@ -148,6 +156,12 @@ if [[ "$VERBOSITY" -gt 1 ]]; then
echo "debug[2]: looping through all globs" 1>&2
fi
if [[ -n "$EXTENSION" ]]; then
if [[ "$VERBOSITY" -ge 1 ]]; then
echo "debug[1]: using backup extension: $EXTENSION" 1>&2
fi
fi
GLOBS="$#"
i=0
while [[ "$i" -lt "$GLOBS" ]]; do
@@ -155,12 +169,13 @@ while [[ "$i" -lt "$GLOBS" ]]; do
echo "debug[2]: found glob: $i" 1>&2
fi
if [[ "$VERBOSITY" -ge 1 ]]; then
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
echo "debug[1]: about to run: git ls-files $1 | xargs $SED -i\"$EXTENSION\" $SED_OPTIONS ${SED_COMMANDS[*]}" 1>&2
else
echo "debug[1]: about to run: git ls-files $1 | xargs $SED -i\"\" ${SED_COMMANDS[*]}" 1>&2
echo "debug[1]: about to run: git ls-files $1 | xargs $SED -i\"$EXTENSION\" ${SED_COMMANDS[*]}" 1>&2
fi
else
if [[ -n "$SED_OPTIONS" ]]; then
@@ -173,9 +188,9 @@ while [[ "$i" -lt "$GLOBS" ]]; do
if [[ -z "$I_FLAG" ]]; then
if [[ -n "$SED_OPTIONS" ]]; then
git ls-files "$1" | xargs "$SED" -i"" "$SED_OPTIONS" "${SED_COMMANDS[@]}"
git ls-files "$1" | xargs "$SED" -i"$EXTENSION" "$SED_OPTIONS" "${SED_COMMANDS[@]}"
else
git ls-files "$1" | xargs "$SED" -i"" "${SED_COMMANDS[@]}"
git ls-files "$1" | xargs "$SED" -i"$EXTENSION" "${SED_COMMANDS[@]}"
fi
else
if [[ -n "$SED_OPTIONS" ]]; then
+88 -22
View File
@@ -7,36 +7,71 @@ efficiency because it ran git ls-files for each `sed` command.
Now it is a bit more thorough and is more efficient (though not perfect). It
allows you to specify a path to `sed`, `sed` options and multiple `sed` commands
(though this always existed). The default behaviour is to use in place editing
**WITHOUT A BACKUP EXTENSION** but you may override the saving to disk with the
`-I` option.
(though this always existed). The _default_ behaviour is to use in place editing
(**WITHOUT A BACKUP EXTENSION**; use `-i` to provide a backup extension) but you
can override the saving to disk with the `-I` option.
## Usage
```sh
usage: sgit [-h] [-V] [-v level] [-x] [-I] [-o sed_options] [-s sed] [-e command] <glob...>
usage: sgit [-h] [-V] [-v level] [-x] [-I] [-i extension] [-o sed_options] [-s sed] [-e command] <glob...>
-h print help and exit
-V print version and exit
-v level set verbosity level
-x turn on tracing (set -x)
-I disable in place editing
-o sed options (don't pass '-')
-i extension set backup extension (default none)
WARNING: sed -i overwrites existing files
WARNING: this will create another file for each file changed
-o sed options (NOTE: don't pass '-'!)
WARNING: use of '-o n' without '-I', can depending on command, empty files
-s sed set path to sed
-e command append sed command to execute on globs
sgit version: 0.0.7-1 12-04-2023
-e command append sed command to to list to execute on globs
sgit version: 0.0.8-1 19-04-2023
```
You **MUST** specify at least one `sed` command and one glob: the sed command by
way of the `-e` option (just like with `sed`); anything after the last option is
a glob. You may specify more than one of each. Specify `-e` for each command.
# A note about the `-i` option and backup extensions
It works like `sed -i` except that the default behaviour of the script is to use
`-i` just with an empty backup extension (this is required for some versions of
`sed` which force that a backup extension actually be provided with the `-i`
option .. I'm looking at you, BSD/macOS `sed`).
# `-i` WARNING: each file edited will result in another file in the working directory
Of course if you have 50 files that are affected then 50 new files will be
created.
# `-i` WARNING: `sed -i` **WILL OVERWRITE EXISTING FILES**!
Please be aware that if a backup file already exists it **WILL** be overwritten!
I won't even try and detect this because it's not how `sed` works and it would
overly complicate the script.
# `-o n` WARNING: invalid use of -o n can empty files!
Because `sed -n` does not print output if you do not use `-I` and you use
substitute you can empty the entire file. For instance **DO NOT** do this:
```sh
./sgit -o n -e 's/.//g' sgit
```
because it would empty `sgit`!
# Examples
## Change in this file (in memory only) `\<sed\>` to be `used` but only show lines changed:
## Change in this file (_IN MEMORY ONLY_) `\<sed\>` to `used` but only show lines changed:
```sh
./sgit -I -o n -e 's/\<sed\>/used/p' README.md
@@ -53,38 +88,69 @@ needs to be:
./sgit -I -o n -e '/\<sed\>/p' .
```
## Change references of `\<sed\>` to be `used` in this file and save it:
## With tracing enabled, change references of `\<sed\>` to `used` in this file and save it:
```sh
./sgit -e 's/\<sed\>/used/p' -v3 -x README.md
./sgit -e 's/\<sed\>/used/g' -x README.md
```
## Change `\<sed\>` to `used` but only if it's on the third line
## With tracing enabled, change references of `\<sed\>` to `used`, duplicating the lines, in this file and save it:
```sh
./sgit -e '3s/\<sed\>/used/g' README.md
./sgit -e 's/\<sed\>/used/p' -x README.md
```
## Verbosely (level 1) change references of `\<sed\>` to `used` in this file and save it:
```sh
./sgit -e 's/\<sed\>/used/g' -v1 README.md
```
## Verbosely (level 3) change references of `\<sed\>` to `used` in this file with a backup as `README.md.bak`
```sh
./sgit -i.bak -e 's/\<sed\>/used/g' -v3 README.md
```
With that you would see something like:
```sh
debug[2]: sed commands: -e s/\<sed\>/used/g
debug[2]: looping through all globs
debug[1]: using backup extension: .bak
debug[2]: found glob: 0
debug[1]: about to run: git ls-files README.md | xargs /opt/local/bin/sed -i".bak" -e s/\<sed\>/used/g
debug[2]: 0 remaining globs
```
Level 2 would not show how many globs remain after each operation.
## Change `\<sed\>` to `used` but only if it's on the first line
```sh
./sgit -e '1s/\<sed\>/used/g' README.md
```
Alternatively you could do one of:
```sh
./sgit -e '3s/\<sed\>/u&/g' README.md
./sgit -e '3s/\(\<sed\>\)/u\1/g' README.md
./sgit -e '1s/\<sed\>/u&/g' README.md
./sgit -e '1s/\(\<sed\>\)/u\1/g' README.md
```
# WARNING: invalid use of -o -n can empty files!
Because `sed -n` does not print output if you do not use `-I` and you use
substitute you can empty the entire file. For instance **DO NOT** do this:
## Change `\<hack\>` to `crack` but only if it's on the third line
```sh
./sgit -o n -e 's/.//g' sgit
./sgit -e '3s/\<hack\>/crack/g' README.md
```
because it would empty `sgit`!
## Installation