Last active
June 9, 2023 05:06
-
-
Save rahogata/1478cfffd07d2087e53b400079d42332 to your computer and use it in GitHub Desktop.
Shell script to edit properties file interactively, add, update, delete, listing properties supported.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# Name: propertyeditor | |
# Desc: add,update,delete, list properties interactively | |
# Args: $1 -> property file to edit. | |
PATH=/bin:/usr/bin:/usr/local/bin | |
DEFAULTFILE="$HOME/rahogata.properties" | |
# ignore signals during file operations | |
################################# | |
# Name: ignoreSignals | |
# Desc: ignore major signals | |
################################# | |
ignoreSignals() { | |
trap '' 1 2 3 15 | |
} | |
################################# | |
# Name: handleSignals | |
# Desc: perform operations for | |
# critical signals | |
################################# | |
handleSignals() { | |
trap "closeEdit;doCleanUp" 1 2 3 15 | |
} | |
################################# | |
# Name: dispalyMenu | |
# Desc: dispaly menu as required | |
################################# | |
displayMenu() { | |
cat << EOH | |
1. Add Property | |
2. Update Property | |
3. Delete Properties | |
4. Show Properties | |
5. Exit | |
EOH | |
} | |
closeEdit() { | |
echo inside closeEdit | |
mv "$PROPERTYFILE" "$PROPERTYFILE.bak" 2>/dev/null | |
mv "$UPDATESF" "$PROPERTYFILE" 2>/dev/null | |
} | |
doCleanUp() { | |
echo inside doCleanUp | |
rm "$UPDATESF.new" 2>/dev/null | |
} | |
################################# | |
# Name: printERROR | |
# Desc: display error message & exit | |
# Args: $@ -> all | |
################################# | |
printERROR() { | |
echo "ERROR: $@" >&2 | |
exit 1 | |
} | |
################################# | |
# Name: printUSAGE | |
# Desc: display usage & exit | |
# Args: $@ -> all | |
################################# | |
printUSAGE() { | |
echo "USAGE: `basename $0` $@" >&2 | |
exit 1 | |
} | |
####################################### | |
# Name: _listingHelper | |
# Desc: helper function to list keys | |
# with and without number | |
# Args: $1 -> n for numbering | |
####################################### | |
_listingHelper(){ | |
OKEYS= | |
i=1 | |
if [ "$1" = "-n" ] ; then | |
OIFS="$IFS" | |
IFS=' | |
' | |
for k in `cat -s "$UPDATESF" | tr -d '\015' | grep -v '^ *[!#]\|^ *$'` ; do | |
OKEYS="$OKEYS | |
$i. $k" | |
i=`expr $i + 1` | |
done | |
IFS="$OIFS" | |
unset OIFS | |
echo "$OKEYS" | |
else | |
cat -s "$UPDATESF" | tr -d '\015' | grep -v '^ *[!#]\|^ *$' | |
fi | |
} | |
####################################### | |
# Name: listKeys | |
# Desc: retrieve list of updated keys | |
# Args: $@ -> includes options | |
####################################### | |
listKeys() { | |
_listingHelper $@ | cut -d= -f1 | |
} | |
###################################### | |
# Name: listValues | |
# Desc: retrieve list of values only | |
# Args: $@ -> includes options | |
###################################### | |
listValues() { | |
_listingHelper $@ | cut -d= -f2- | |
} | |
###################################### | |
# Name: getKey | |
# Desc: retrieve key from $UPDATESF | |
# Args: $1 -> key index | |
###################################### | |
getKey() { | |
echo "`listKeys | sed "$1!d" | tr -d ' '`" | |
} | |
###################################### | |
# name: getvalue | |
# desc: retrieve value from $updatesf | |
# args: $1 -> key index | |
###################################### | |
getvalue() { | |
echo "`listValues | sed "$1!d" | tr -d ' '`" | |
} | |
###################################### | |
# Name: getComment | |
# Desc: retrieve comment line from | |
# $UPDATESF | |
# Args: $1 -> key name | |
###################################### | |
getComment() { | |
echo "`awk ' | |
{ | |
if ( $0 ~ pattern ) { | |
print comments; | |
} | |
else if ( $0 !~ /^ *[!#]/ ) { | |
comments=""; | |
} | |
else { | |
comments=comments"\n"$0; | |
} | |
}' pattern="^ *$1" "$UPDATESF" | grep -v '^ *$'`" | |
} | |
####################################### | |
# Name: promptRESPONSE | |
# Desc: display prompt and get response | |
# Args: $1 -> prompt | |
# $2 -> old value | |
# $3 -> true if blank allowed | |
####################################### | |
promptRESPONSE() { | |
DEF_VAL="$2" | |
RESPONSE= | |
if [ -z "$3" ] || [ "$3" = "false" ] ; then | |
while [ -z "$RESPONSE" ] | |
do | |
printf "$1:[$2] " | |
read RESPONSE | |
done | |
else | |
printf "$1:[$2] " | |
read RESPONSE | |
fi | |
RESPONSE="${RESPONSE:-"$DEF_VAL"}" | |
unset DEF_VAL | |
} | |
######################################## | |
# Name: promptYESNO | |
# Desc: ask yes/no question | |
# Args: $1 -> prompt | |
# $2 -> default answer | |
######################################## | |
promptYESNO() { | |
YESNO= | |
printf "$1(y/n):[$2] " | |
read YESNO | |
case "$YESNO" in | |
[yY]|[yY][eE][sS]) YESNO="y" ;; | |
[nN]|[nN][oO]) YESNO="n" ;; | |
*) YESNO="$2" ;; | |
esac | |
} | |
############################################### | |
# Name: hasProperty | |
# Desc: check if property already exist | |
# Args: $1 -> key | |
# $2 -> properties list variable or file | |
############################################### | |
hasProperty() { | |
_ECHO="echo" | |
if [ -f "$2" ] ; then | |
_ECHO="cat" | |
fi | |
if [ "`$_ECHO "$2" | grep "^$1"`" = "" ] ; then | |
return 1 | |
fi | |
} | |
########################################### | |
# Name: addProperty | |
# Desc: add property to list of properties | |
# interactively | |
# Args: $1 -> key | |
# $2 -> value | |
# $3 -> comment | |
########################################### | |
addProperty() { | |
ignoreSignals | |
printf "#%s\n%s=%s\n" "$3" "$1" "$2" >> "$UPDATESF" | |
handleSignals | |
} | |
########################################## | |
# Name: updateProperty | |
# Desc: update value of property | |
# Args: $1 -> key line number | |
# $2 -> value | |
########################################## | |
updateProperty() { | |
ignoreSignals | |
PKEY="`getKey $1`" | |
if [ ! -z "$PKEY" ] ; then | |
sed "s/^ *${PKEY}.*$/${PKEY}="${PVAL}"/" "$UPDATESF" > "$UPDATESF.new" 2>/dev/null | |
mv "$UPDATESF.new" "$UPDATESF" | |
fi | |
handleSignals | |
} | |
########################################## | |
# Name: deleteProperty | |
# Desc: delete a property | |
# Args: $1 -> key serial no. | |
########################################## | |
deleteProperty() { | |
ignoreSignals | |
PKEY="`getKey $1`" | |
PCOMMENT="`getComment "$PKEY"`" | |
if [ ! -z "$PKEY" ] ; then | |
grep -v "^ *$PKEY" "$UPDATESF" | grep -v "$PCOMMENT" > "$UPDATESF.new" 2>/dev/null | |
mv "$UPDATESF.new" "$UPDATESF" | |
fi | |
handleSignals | |
} | |
# main() | |
handleSignals | |
# first print usage for -h option | |
if [ $# -eq 1 ] && [ "$1" = "-h" ] ; then | |
printUSAGE "[options] [file]" | |
fi | |
# shift args all but last one | |
shift `expr $# - 1` >/dev/null 2>&1 | |
# set variable for file | |
PROPERTYFILE="${1:-$DEFAULTFILE}" | |
# check file existence. | |
if [ ! -f "$PROPERTYFILE" ] ; then | |
printERROR "Property file $PROPERTYFILE does not exists or not a file." | |
fi | |
# act on a copy of the file | |
UPDATESF="pupdates.$$" | |
cp "$PROPERTYFILE" "$UPDATESF" | |
while : | |
do | |
echo | |
displayMenu | |
# ask choice | |
promptRESPONSE "Choose" 5 true | |
case "$RESPONSE" in | |
# add property for choice 1 | |
1) | |
while : | |
do | |
promptRESPONSE "Key" | |
PKEY="$RESPONSE" | |
promptRESPONSE "Value" "" true | |
PVAL="$RESPONSE" | |
promptRESPONSE "Comment" "" true | |
PCOMMENT="$RESPONSE" | |
if hasProperty "$PKEY" "$UPDATESF" ; then | |
echo "Property already exists." | |
read | |
break | |
fi | |
addProperty "$PKEY" "$PVAL" "$PCOMMENT" | |
promptYESNO "Continue adding property" n | |
if [ "$YESNO" = "n" ] ; then | |
break | |
fi | |
done | |
;; | |
2) | |
while : | |
do | |
listKeys -n | |
promptRESPONSE "Choose" "" true | |
KEYIDX="$RESPONSE" | |
if [ -z "$KEYIDX" ] ; then | |
break | |
fi | |
promptRESPONSE "Value" "`getvalue $KEYIDX`" true | |
PVAL="$RESPONSE" | |
updateProperty "$KEYIDX" "$PVAL" | |
echo "Property updated successfully." | |
promptYESNO "Update some more" n | |
if [ "$YESNO" = n ] ; then | |
break | |
fi | |
done | |
;; | |
3) while : | |
do | |
listKeys -n | |
promptRESPONSE "Choose" "" true | |
if [ -z "$RESPONSE" ] ; then | |
break | |
fi | |
promptYESNO "Delete selected?" n | |
if [ "$YESNO" = n ] ; then | |
break | |
fi | |
deleteProperty $RESPONSE | |
echo "Property deleted successfully." | |
promptYESNO "Continue deleting?" n | |
if [ "$YESNO" = n ] ; then | |
break | |
fi | |
done | |
;; | |
4) | |
echo | |
awk -F= '!/^ *[!#]|^ *$/ { | |
i = i + 1; | |
printf "%d. %s",i, $1; | |
$1="->"; | |
print $0; | |
}' "$UPDATESF" | |
promptYESNO "Press Enter to continue" y | |
;; | |
*) if [ "$RESPONSE" -eq 5 ] ; then | |
break | |
fi | |
;; | |
esac | |
done | |
closeEdit | |
doCleanUp |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment