Reputation: 1642
I am new to shell programming and had to do the following task. I have a file with following line at line number 28 (static).
page.sysauth = "Admin"
I wanted to replace this line using a shell script each time a new entry to sysauth be made.
page.sysauth = {"Admin", "root"} page.sysauth = {"Admin", "root", "newAdmin"} etc.
Also I would want to remove entries from this sysauth variable
page.sysauth = {"Admin", "root", "newAdmin"}
page.sysauth = {"Admin", "root"}
page.sysauth = "Admin"
Please provide pointers in achieving this.
EDIT: Thank you for the inputs: Assumption: First entry should be present. eg: page.sysauth="Admin" Script fails when page.sysauth=______ (empty).
Here's my working script sysauth_adt.sh
#!/bin/bash
add () {
sed -i~ -e '28 { s/= "\(.*\)"/= {"\1"}/; # Add curlies to a single entry.
s/}/,"'"$entry"'"}/ # Add the new entry.
}' "$file"
}
remove () {
sed -i~ -e '28 { s/"'"$entry"'"//; # Remove the entry.
s/,}/}/; # Remove the trailing comma (entry was last).
s/{,/{/; # Remove the leading comma (entry was first).
s/,,/,/; # Remove surplus comma (entry was inside).
s/{"\([^,]*\)"}/"\1"/ # Remove curlies for single entry.
}' "$file"
}
if (( $# == 3 )) ; then
file=$1
action=$2
entry=$3
if [[ $action == add ]] ; then
if head -n28 $1 | tail -n1 | grep -q $3 ; then
echo 0
else
add
fi
elif [[ $action == remove ]] ; then
if head -n28 $1 | tail -n1 | grep -q $3 ; then
remove
else
echo 0
fi
fi
else
echo "Usage: ${0#*/} file (add | remove) entry" >&2
exit 1
fi
Upvotes: 1
Views: 60
Reputation: 10039
awk -F '[[:blank:]]+=[[:blank:]]+' '
# load every single entry
NR != 28 && FNR == NR && $1 ~ /^page.sysauth$/ && $0 !~ /\{.*\}/ { aSysAdd[ ++SysAdd] = $2}
# load special line 28
NR == 28 {
gsub( /^{|}$/, "", Datas = $2)
SysOrg = split( Datas, aSysOrg, /[[:blank:]]*,[[:blank:]]*/)
}
# print standard lines
FNR != NR && $1 !~ /^page.sysauth$/ { print }
# print line 28 (new version)
FNR != NR && FNR == 28 {
printf "page.sysauth = {" aSysOrg[ 1]
for( i = 2; i <= SysOrg; i++) printf ", %s", aSysOrg[ i]
for( i = 1; i <= SysAdd; i++) printf ", %s", aSysAdd[ i]
print "}"
# don't print other page.sysauth
}
' YourFile YourFile > YourFile.new
mv YourFile.new YourFile
Using awk with 2 read (the double YourFile
is not an error and mandatory)
Upvotes: 1
Reputation: 241858
If your entries will always be single words with no commas, you can use simple sed scripts:
#!/bin/bash
add () {
sed -i~ -e '28 { s/= "\(.*\)"/= {"\1"}/; # Add curlies to a single entry.
s/}/,"'"$entry"'"}/ # Add the new entry.
}' "$file"
}
remove () {
sed -i~ -e '28 { s/"'"$entry"'"//; # Remove the entry.
s/,}/}/; # Remove the trailing comma (entry was last).
s/{,/{/; # Remove the leading comma (entry was first).
s/,,/,/; # Remove surplus comma (entry was inside).
s/{"\([^,]*\)"}/"\1"/ # Remove curlies for single entry.
}' "$file"
}
if (( $# == 3 )) ; then
file=$1
action=$2
entry=$3
if [[ $action == add ]] ; then
add
elif [[ $action == remove ]] ; then
remove
fi
else
echo "Usage: ${0#*/} file (add | remove) entry" >&2
exit 1
fi
The script doesn't check whether an entry already exists in the list when adding or removing it. For more complicated tasks, I'd probably switch to a real programming language.
Upvotes: 1