1. Overview

Properties files contain properties names in the form of dot delimited strings.

This structure captures well the properties’ hierarchy. However, using such names directly is difficult in bash scripts.

In this tutorial, we’re going to access such properties with as few as possible changes to their name’s structure.

2. Problem Statement

Let’s examine a simple property file test.properties:

# test.properties
db.test.user=test user
db.test.passwd=password

As the first attempt, let’s turn properties names into bash variables. For this purpose, let’s just source the properties file:

#!/bin/bash

source test.properties

echo "User Id (db.test.user) = " $db.test.user
echo "user password (db.test.passwd) =" $db.test.passwd

Unfortunately, we’re going to end up with errors:

test.properties: line 2: db.test.user=test user: command not found
test.properties: line 3: db.test.passwd=password: command not found
User Id (db.test.user) =  .test.user
user password (db.test.passwd) = .test.passwd

This approach fails because the dot is an illegal character in the bash variable’s name.

3. Mapping out Dots From the Property Name

Let’s just change the dots into some legal character.

The bash variable’s name may contain only digits, letters, and underscores. Therefore we need to choose the underscore ‘_’:

#!/bin/sh

file="./test.properties"

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

echo "User Id (db.test.user) =         " ${db_test_user}
echo "user password (db.test.passwd) = " ${db_test_passwd}

We read key and value separately, with the equal sign as a separator. Next, tr translates dots to underscores in the property name. Finally, eval defines a bash variable with a new name.

Now let’s examine the result produced by this script:

User Id (db.test.user) =          test user
user password (db.test.passwd) =  password

Within this approach, we create a bunch of bash variables, one for each property. Subsequently, we refer to properties using mapped names.

4. Use Array as a Lookup Table

Since Bash 4.0, we can benefit from associative arrays. So, let’s use the property’s name as a key to its values:

#!/bin/bash

# array declaration
declare -A props

file="./test.properties"
while IFS='=' read -r key value; do
   props["$key"]="$value"
done < "$file"

echo "User Id (db.test.user) =         " ${props["db.test.user"]}
echo "user password (db.test.passwd) = " ${props["db.test.passwd"]}

The key has no limitations on its form. Therefore we can access properties with their own names.

5. Picking out Variables From File With a Wrapper Function

Let’s create a function that searches for a property’s name in the properties file. As a result, it returns the property’s value.

Under the hood, we’re going to use the grep command and subsequently cut off the property value from the found line:

#!/bin/bash

file="./test.properties"

function prop {
    grep "${1}" ${file} | cut -d'=' -f2
}

echo "User Id (db.test.user) =         " $(prop 'db.test.user')
echo "user password (db.test.passwd) = " $(prop 'db.test.passwd')

We refer to the property using its original name. However, each picking of variable demands grepping the whole file again. Therefore, this method may be slow for large property files.

6. Conclusion

In this article, we learned how to parse a properties file.

First, we kept the properties as bash variables at the cost of modifying their names.

Next, we stored them in the associative array, which returned the value bound to a given name.

Finally, we just searched for properties in the file using grep.