Parse config file in bash?

I need my bash script to parse a configuration file. The configuration file needs to hold some specific information:

- a mapping of keys and their values
- a large block of text
- some lines might be comments
- some lines might be whitespace

I imagine one possible format for the config file (although it doesn't have to be done this way) is something like this:

[mapping]

; a comment here
foo=bar
asdf=qwerty

; more comments here
aaa=bbb
banana=orange

[text]
alsidjf alsif jasli fjasli fajslif ja
 ija liaj ilas jalsi jasl
 ijas lifjas lifjas lisja lij

Open in new window



How can I parse something like this in Bash? Do I have to write the parsing myself, or does Bash have some built in config-file-parsing abilities?
LVL 31
Frosty555Asked:
Who is Participating?
 
Frosty555Connect With a Mentor Author Commented:
Hi guys,

I didn't want to make it a bash script because it needs to be edited and created by people who do not necessarily know bash. Wesly, your awk line leaves the comments in and doesn't trim any spaces.

I ended up parsing the file through a much larger bash script that was essentially a state machine that looped through it line by line and split out the parts that it needed.

My requirements for the mapping file changed a little over the course of this project. I now needed to have a [mapping], [postupgrade] and [preupgrade] sections.

Here's how I ended up doing it

    # parse the mapping file
    mode=none
    rm -f /tmp/postupgrade.sql /tmp/preupgrade.sql /tmp/mapping.txt /tmp/upgrade.sql

    cat "$mapfile" | while read line; do

        # trim whitespace off the beginning and end of the line
        line=`echo "$line" | awk '{ gsub(/^[ \t]+|[ \t]+$/, ""); print }'`

        # change mode
        if [ "$line" = "[mapping]" ]; then
            mode=mapping
            #echo "Entered mapping mode"
            continue
        fi
        if [ "$line" = "[postupgrade]" ]; then
            mode=postupgrade
            #echo "Entered postupgrade mode"
            continue
        fi
        if [ "$line" = "[preupgrade]" ]; then
            mode=preupgrade
            #echo "Entered preupgrade mode"
            continue
        fi

        case "$mode" in
            mapping)
                if [ "${line:0:1}" == ";" ] || [ -z "$line" ]; then
                    :
                    #echo "discarded line: $line"
                else
                    echo "$line" >>/tmp/mapping.txt
                    #echo "mapping line: $line"
                fi
                ;;

            postupgrade)
                echo "$line" >>/tmp/postupgrade.sql
                #echo "postupgrade line: $line"
                ;;

            preupgrade)
                echo "$line" >>/tmp/preupgrade.sql
                #echo "preupgrade line: $line"
                ;;

            *)
                #echo "discarded line: $line"
        esac

Open in new window


Then I followed a different expert's suggestion in another question for how exactly to parse the mapping.txt file further using awk.
0
 
edster9999Commented:
How about you keep it simple and make the config file a script.

so the main script includes it with something like

#!/bin/bash
MY_DIR=`dirname $0`
source $MY_DIR/config.sh

echo "foo is set to $foo and asdf is set to $asdf"

echo -e "The text block is $text"




and the config file is :

# [mapping]
# a comment here

foo="bar"
asdf="qwerty"

# more comments here
aaa="bbb"
banana="orange"

# [text]
text="alsidjf alsif jasli fjasli fajslif ja\n\
 ija liaj ilas jalsi jasl\n\
 ijas lifjas lifjas lisja lij\n"

Open in new window

0
 
wesly_chenCommented:
Just need the key and value pairs?

awk '/\=/ {print}'  /path-to-config-file
0
 
Frosty555Author Commented:
Ended up coding it myself.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.