#!/bin/sh usage () { printf "Usage $0 " echo << "EOF" OPTIONS... [FILTER] Print the parsed config file filtering by the keys Arguments: -f file read configuration from a file, uses /dev/sdtin otherwise -v only print values -c n print the last [n] EOF } # parse a single config file line # parse_line() { [ "$#" = 0 ] && return local line="$@" local key=$1 shift local value="$@" value=${value%#*} case $key in "include") cat $value | parse return ;; "]") IFS=. set -- $list list="${*%${!#}}" IFS=" " printf "\n" return ;; "}") [ "$level" = "${level%.*}" ] && level="" || level=${level%.*} return ;; esac case ${value##* } in "{") level="${level}${level:+.}${key}" ;; "[") list="${list}${list:+.}${key}" printf "$level${level:+.}$key:" ;; *) [ "${#list}" = "0" ] && printf "$level${level:+.}$key:$value\n" || printf "$line " ;; esac } # print the parsed values from the config file in key:value format # parse () { local file="$1" export level="" export list="" while IFS= read -r line; do parse_line $line done < "/dev/stdin" } # Use the env variable if exists [ -z ${CONF_FILE} ] && CONF_FILE="/dev/stdin" # initialise options print_keys=true count= while getopts ":f:c:v" opt; do case "${opt}" in f) [ "${OPTARG}" = "-" ] && CONF_FILE="/dev/stdin" || CONF_FILE="${OPTARG}" ;; v) print_keys=false ;; c) count="${OPTARG}q" ;; *) esac done shift $((OPTIND-1)) [ $# = 0 ] && pattern=".*" || pattern=$(echo $@ | sed "s/\*/[^:]*/g") $print_keys && pattern="s/^($pattern:.+)/\1/p;${count}" || pattern="s/^$pattern:(.+)/\1/p;${count}" # strip whitespace sed "s/^\s*#.*$\|\s(\s\+)\|^\s\|\s^\|;*$//g" $CONF_FILE | parse $@ | sed -rn $pattern