Bash Script Properties File Using '.' in Variable Name

Bash Script Properties File Using '.' in Variable Name

Load them into an associative array. This will require your shell to be bash 4.x, not /bin/sh (which, even when a symlink to bash, runs in POSIX compatibility mode).

declare -A props
while read -r; do
[[ $REPLY = *=* ]] || continue
props[${REPLY%%=*}]=${REPLY#*=}
done <input-file.properties

...after which you can access them like so:

echo "${props[this.prop.name]}"

If you want to recursively look up references, then it gets a bit more interesting.

getProp__property_re='[$][{]([[:alnum:].]+)[}]'
getProp() {
declare -A seen=( ) # to prevent endless recursion
declare propName=$1
declare value=${props[$propName]}
while [[ $value =~ $getProp__property_re ]]; do
nestedProp=${BASH_REMATCH[1]}
if [[ ${seen[$nestedProp]} ]]; then
echo "ERROR: Recursive definition encountered looking up $propName" >&2
return 1
fi
value=${value//${BASH_REMATCH[0]}/${props[$nestedProp]}}
done
printf '%s\n' "$value"
}

If we have props defined as follows (which you could also get by running the loop at the top of this answer with an appropriate input-file.properties):

declare -A props=(
[glassfish.home.dir]='${app.install.dir}/${glassfish.target}'
[app.install.dir]=/install
[glassfish.target]=target
)

...then behavior is as follows:

bash4-4.4$ getProp glassfish.home.dir
/install/target

How to store property file keys into variables in a shell script after reading them

You can use eval. Just be careful with this command though. It can be devastating. Unfortunately unlike bash, sh does not support declare.

$ cat property.txt
USERNAME = "Me"
PASSWORD = "Secret"
DB_NAME = "THINGDB"

$ cat shell.sh
#!/bin/sh

while IFS= read -r line; do
key="${line%% =*}"
value="${line#*= }"
eval "$key"="$value" # For ash, dash, sh.
# declare "$key"="$value" # For bash, other shells.
done < property.txt

echo "username: $USERNAME"
echo "password: $PASSWORD"
echo "db_name: $DB_NAME"

$ ./shell.sh
username: Me
password: Secret
db_name: THINGDB

How to read properties file in Unix script where key is in another user input variable

You could use awk to get this.

In place of your echo $data put:

awk -F"=" -v data=$data '$1==data{print $2}' cancellation.properties

Which says "Split each record in your cancellation.properties file by an equal sign. If the first field is the value in variable $data (which is the variable data in your awk script set by that -v flag since you can't use shell variables directly in awk) then output the second field.

Also, now that read your question more thoroughly, it looks like you are including your .properties file at the top of the script. This may not be the best answer for you if you wish to proceed. See @cyrus comment to your question where it's noted to quote your variable assignment.

How to read a .properties file which contains keys that have a period character using Shell script

As (Bourne) shell variables cannot contain dots you can replace them by underscores. Read every line, translate . in the key to _ and evaluate.

#/bin/sh

file="./app.properties"

if [ -f "$file" ]
then
echo "$file found."

while IFS='=' read -r key value
do
key=$(echo $key | tr '.' '_')
eval ${key}=\${value}
done < "$file"

echo "User Id = " ${db_uat_user}
echo "user password = " ${db_uat_passwd}
else
echo "$file not found."
fi

Note that the above only translates . to _, if you have a more complex format you may want to use additional translations. I recently had to parse a full Ant properties file with lots of nasty characters, and there I had to use:

key=$(echo $key | tr .-/ _ | tr -cd 'A-Za-z0-9_')

shell script to pass values properties file in java

I believe the easiest way to achieve your goal is to always execute the substitutions on the untouched template file rather than trying to work on the previous version of the resulting file :

# produce a first version of the file.properties 
sed -e 's/USERNAME/user1/' -e 's/PASS/pass1/' file.properties.template > file.properties

# succesfully produce a second version of the file.properties
sed -e 's/USERNAME/user2/' -e 's/PASS/pass2/' file.properties.template > file.properties

Another alternative would be to change the input (or code?) of your script so that you would base your search&replace operation not on placeholder values but rather on the properties names :

$ cat test.sh
#!/bin/bash

target=$1
shift

while key=$1 && value=$2 && shift 2; do
sed -i "s/^$key=.*/$key=$value/" $target
done

$ cat test.props
mysql.hostname=HOSTNAME
mysql.username=USERNAME
mysql.pass=PASS

$ ./test.sh test.props mysql.username sa mysql.pass clearTextPasswordsAreTerrible

$ cat test.props
mysql.hostname=HOSTNAME
mysql.username=sa
mysql.pass=clearTextPasswordsAreTerrible

$ ./test.sh test.props mysql.username secondTry mysql.pass successfullyModified

$ cat test.props
mysql.hostname=HOSTNAME
mysql.username=secondTry
mysql.pass=successfullyModified


Related Topics



Leave a reply



Submit