$ a="hello world"
$ echo ${a// /_}
hello_world
bash(1) によると:
${parameter/pattern/string}
パターン置換。パス名の展開と同様に、パターンが展開されてパターンが生成されます。パラメータが展開され、その値に対するパターンの最長一致が文字列に置き換えられます。パターンが / で始まる場合、パターンのすべての一致が置き換えられます
ひも付き。通常、最初の一致のみが置き換えられます。パターンが # で始まる場合、パラメータの展開された値の先頭で一致する必要があります。パターンが % で始まる場合は、パラメータの展開された値の最後で一致する必要があります。文字列が null の場合、パターンの一致が削除され、/ に続くパターンが省略される場合があります。 parameter が @ または * の場合、置換操作は各定位置パラメーターに順番に適用され、結果のリストが展開されます。 parameter が @ または * で添字付けされた配列変数である場合、置換操作は配列の各メンバーに順番に適用され、展開は結果のリストになります。
以下を試すことができます:
str="${str// /_}"