0

I'm looking for a Bash equivalent for the following python code:

template = 'The {part} on the {vehicle} goes {action} and {action}.'

template.format(part='wheels', vehicle='bus', action='round')
## or ##
vals = {'part': 'wheels', 'vehicle': 'bus', 'action': 'round'}
template.format(**vals)

desired result:

'The wheels on the bus go round and round.'

Does bash have a feature like this? If not, is there a way to simulate this behaviour?


I know I can format strings with printf like this:

template="The %s on the %s go %s and %s."
part="wheels"
vehicle="bus"
action="round"

printf "${template}" ${part} ${vehicle} ${action} ${action}
## or ##
vals=(${part} ${vehicle} ${action} ${action})
printf "${template}" ${vals[@]}

...but I don't want to have to provide the same value more than once if it appears in the string multiple times, like "action" does.

I wish I could do something like this:

declare -A vals=(["part"]="wheels" ["vehicle"]="bus" ["action"]="round")
printf "${template}" ${vals[@]}

I am also aware of string replacement like this:

string="${string//old/new}"

which I thought I could put into a function which iterates over an associative array and replaces the keys with values, but I couldn't get this to work mainly because passing associative arrays as arguments is non-trivial. I'm sure I could eventually find a workaround, but the workaround needs to be less onerous than simply putting up with printf's shortcomings.

Cyrus
  • 84,225
  • 14
  • 89
  • 153
ibonyun
  • 425
  • 3
  • 11

1 Answers1

0

Using envsubst, you could do:

template='The ${part} on the ${vehicle} goes ${action} and ${action}.'
part="wheels" vehicle="bus" action="round" envsubst <<<"$template"

or

template='The ${part} on the ${vehicle} goes ${action} and ${action}.'

export part="wheels"
export vehicle="bus"
export action="round"

envsubst '$part $vehicle $action' <<<"$template"

Or for a longer text, use a here-document:

part="wheels"
vehicle="bus"
action="round"

cat <<EOF
The ${part}
  on the ${vehicle}
goes ${action}
  and ${action}.
EOF
Freddy
  • 4,548
  • 1
  • 7
  • 17