Alex
Alex

Reputation: 44265

How to get a bash parameter substitution to work properly?

I have a bash variable like

[email protected]:/root/test

and want to access the different parts (user, host, path, in which the user is optional). I tried:

path=${var#*:*}
user=${var%*@*}
host=${{var#*@*}%*:*}

While the expressions for PATH and user work as expected (i.e. USER has string root and path has string /root/test), the expression for getting host (i.e. the part between the @ sign and the : sign) gives a bad substitution error. Is there a simple/elegant way to fix this expression in a single line, in order to extract the 'middle' part of the original variable?

Additional information: It also must work when no user is given, i.e. in the following case without a user (and without a '@' sign), the variable user must be empty, but the other variables must be filled accordingly:

var=283.45.67.89:/root/test

I expect the following result

path=/root/test
host=283.45.67.89
user=

Upvotes: 1

Views: 775

Answers (2)

choroba
choroba

Reputation: 241748

Use lowercase variable names. $PATH and $USER are special.

To parse the string, you can use a regular expression:

[[ $var =~ (.*)@(.*):(.*) ]]
user=${BASH_REMATCH[1]} 
host=${BASH_REMATCH[2]} 
path=${BASH_REMATCH[3]} 

Update: For a possibly missing user, you can change it to

[[ @$var =~ (.*)@(.*):(.*) ]]
user=${BASH_REMATCH[1]#@}

Upvotes: 3

Morten Zilmer
Morten Zilmer

Reputation: 15924

A temporary variable (tmp) may amend the problem with bad substitution error, and this work both with and without user:

path=${var#*:}      # Get path
tmp=${var%:*}       # Get all before ":"
host=${tmp#*@}      # Get host by removing any user and "@"
tmp=${tmp%${host}}  # Get any user and "@" by prevoving host
user=${tmp%@}       # Remove any "@" from user

Upvotes: 0

Related Questions