Guillaume D
Guillaume D

Reputation: 2326

reading parameter value with regex in shell

I want to simply read this file

FOO=1
BAR=/^@djrhaali$$sdf

with some shell function like this:

FOO=$(GetParam "FOO")
BAR=$(GetParam "BAR")

so to retrieve the content of each config parameter in the file (after the "="), I need something like:

GetParam() {
   cat  myFile | grep '^${$1}=' | grep -oP '(?<${$1}=).*'
}

which gives me

grep: syntax error in subpattern name (missing terminator)


Note:

I'm using grep from the git bash (grep (GNU grep) 2.27)

Upvotes: 0

Views: 291

Answers (2)

Gilles Qu&#233;not
Gilles Qu&#233;not

Reputation: 185126

I would suggest another proper approach, using 's associative array :

#!/bin/bash

declare -A arr
while IFS='=' read -r key value; do
    arr[$key]="$value"
done < InputFile

getParam() { echo "${arr[$1]}";  }

Now using declarated function :

getParam foo
1

and

getParam bar
/^@djrhaali$$sdf

 Notes :

  • in bash, function call are not like func(1) but func 1
  • your solution using grep is not as reliable as this solution
  • no need to do cat file | grep foobar but only grep foobar file
  • avoid using UPPER CASE variables, they are reserved for system use
  • learn how to quote properly in shell, it's very important :

    "Double quote" every literal that contains spaces/metacharacters and every expansion: "$var", "$(command "$var")", "${array[@]}", "a & b". Use 'single quotes' for code or literal $'s: 'Costs $5 US', ssh host 'echo "$HOSTNAME"'. See
    http://mywiki.wooledge.org/Quotes
    http://mywiki.wooledge.org/Arguments
    http://wiki.bash-hackers.org/syntax/words

Upvotes: 2

Inian
Inian

Reputation: 85590

Function arguments in shell aren't named as in other languages like C. They are handled by special variables that represent the argument list. For e.g. "$@" refers to the entire list of arguments. So the first argument passed is named $1, $2 upto the last argument.

Also variables in shell are not interpolated under single quotes. You need to double quote them for it to expand.

The reported problem of missing terminator is because of an incorrect PCRE look-behind regex, that was missing a = symbol

GetParam() {
    [ -z "$1" ] && { printf 'arg empty\n' >&2; }
    grep "${1}=" file | grep -oP "(?<=${1}=).*"
    #                               ^^^^ missing = symbol
}

Look at the usage of grep on the input file directly avoiding useless invocation of cat. Avoiding multiple grep invocations, you can simply use awk for this as

GetParam() {
    [ -z "$1" ] && { printf 'arg empty\n' >&2; }
    awk -F= -v var="$1" '$1 == var { print $2 }' file 
}

With this definitions, you can now use the functions as

fooval=$(GetParam FOO)
barval=$(GetParam BAR)

Upvotes: 1

Related Questions