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
Print Differences of File1 to File2 Without Deleting Anything from File2
R Programming - Submitting Jobs on a Multiple Node Linux Cluster Using Pbs
How Can a Program Detect If It Is Running as a Systemd Daemon
Fail If a Script Expects Input or Entering Passwords
Linux Equivalent of Windows Dll Forwarders or MACos Reexport_Library
Python3 Unicodeencodeerror When Run via Synology Task Scheduler
Arm: Disabling Mmu and Updating Pc
Filter a Content File to Table
How to Find Process Using Tcp Port
Shell Script Won't Recognize Heredoc Delimiter
Using Ssh to Run a Cleartool Command with Agruments on Remote a Linux MAChine
How to Pass a Complete Argument List in Bash While Keeping Mulitword Arguments Together
Differentiate Between Exit and Session Timeout
Determine Vm Size of Process Killed by Oom-Killer
Wget: Unsupported Scheme on Non-Http Url