Replace spaces with underscores via BASH
Solution 1
You could try the following:
str="${str// /_}"
Solution 2
$ a="hello world"
$ echo ${a// /_}
hello_world
According to bash(1):
${parameter/pattern/string}
Pattern substitution. The pattern is expanded to produce a pattern just as in pathname expansion. Parameter is expanded and the longest match of pattern against its value is replaced with string. If pattern begins with /, all matches of pattern are replaced
with string. Normally only the first match is replaced. If pattern begins with #, it must match at the beginning of the expanded value of parameter. If pattern begins with %, it must match at the end of the expanded value of parameter. If string is null, matches of pattern are deleted and the / following pattern may be omitted. If parameter is @ or *, the substitution operation is applied to each positional parameter in turn, and the expansion is the resultant list. If parameter is an array variable subscripted with @ or *, the substitution operation is applied to each member of the array in turn, and the expansion is the resultant list.
Solution 3
Pure bash:
a="hello world"
echo "${a// /_}"
OR tr:
tr -s ' ' '_' <<< "$a"
Solution 4
With sed
reading directly from a variable:
$ sed 's/ /_/g' <<< "$a"
hello_world
And to store the result you have to use the var=$(command)
syntax:
a=$(sed 's/ /_/g' <<< "$a")
For completeness, with awk
it can be done like this:
$ a="hello my name is"
$ awk 'BEGIN{OFS="_"} {for (i=1; i<NF; i++) printf "%s%s",$i,OFS; printf "%s\n", $NF}' <<< "$a"
hello_my_name_is
Solution 5
Multiple spaces to one underscore
This can easily be achieved with a GNU shell parameter expansion. In particular:
${parameter/pattern/string}
If pattern begins with
/
, all matches of pattern are replaced with string.
with +(pattern-list)
Matches one or more occurrences of the given patterns.
Hence:
$ a='hello world example'
$ echo ${a// /_}
hello_world____example
$ echo ${a//+( )/_}
hello_world_example
However, for this to work in a bash script two amendments need to be made:
- The parameter expansion requires encapsulation in double quotes
" "
to prevent word splitting with the input field separator$IFS
. - The
extglob
shell option needs to be enabled using theshopt
builtin, for extended pattern matching operators to be recognised.
The bash script finally looks like this:
#!/usr/bin/env bash
shopt -s extglob
a='hello world example'
echo "${a//+( )/_}"
Related videos on Youtube
Ayush Mishra
Updated on September 22, 2021Comments
-
Ayush Mishra over 2 years
Suppose i have a string, $str. I want $str to be edited such that all the spaces in it are replaced by underscores.
Example
a="hello world"
I want the final output of
echo "$a"
to be hello_world
-
user1587504 over 10 years+1 for just pure bash syntax!. Would like to know what's it doing behind scenes. Looks like it is doing 'sed' replacement operations. Any bash manual states for using such syntax?.
-
William Hay over 10 yearsNeither of these appears to deal with more than one space.
-
anubhava over 10 years@user1587504: I believe
falsetru
has added relevant man section for thisPattern substitution
-
fedorqui over 10 years@WilliamHay you are right, didn't check with more than one space. Updated to use
sed .../g
, as default was doing it just once. -
user1587504 over 10 years@fedorqui +1 for letting know usage of direct variable without echo piping to sed. I donot see direct help for this: '<<<' . Where is it defined in man pages. Could you please point me?
-
fedorqui over 10 years@user1587504 they are called "Here Strings". See linux.die.net/abs-guide/x15683.html for more reference. They are useful.
-
user1587504 over 10 years@fedorqui . Thanks! for letting me know. I did used one with '<<' to check some EOF character when using isql inside a script. Usage of <<< is nice. ..
-
Amesys about 5 yearsUpping this for the reference to bash's documentation, missing in other answers.
-
Maske about 2 yearsThe aclaration for that to work in bash script is vital, thanks!