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:
1 parent
fae013b322
commit
baf357a23f
2 files changed
+115
-34
No files matched your search
@@ -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
@@ -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
|
||||
|
||||
Reference in new issue
Block a user