309

I need to replace a space ( ) with a dot (.) in a string in bash.

I think this would be pretty simple, but I'm new so I can't figure out how to modify a similar example for this use.

Brian Leishman
  • 8,155
  • 11
  • 57
  • 93

7 Answers7

535

Use inline shell string replacement. Example:

foo="  "

# replace first blank only
bar=${foo/ /.}

# replace all blanks
bar=${foo// /.}

See http://tldp.org/LDP/abs/html/string-manipulation.html for more details.

Brian Clapper
  • 25,705
  • 7
  • 65
  • 65
  • 7
    While this solution is good when dealing with short strings (the common case, I guess) one may prefer `tr` for long strings. On my system `tr` outperforms bash starting at strings with more than `1000` characters. It seems like bash's time complexity is worse than linear. A small test: `x="$(tr -dc 'a-z \n' – Socowi Dec 21 '19 at 11:22
  • 1
    @Socowi Playing with 1Mb stored in a variable is not really usual! Upto more than 10Kb, bash seem staying quicker than forking to `tr`!... Depending on available memory and hw resources... But you're right!: Depending on kind of job to do, dedicated tools stay more efficient! – F. Hauri - Give Up GitHub Dec 21 '19 at 12:20
  • For escaped characters like newlines, make sure to search for `$'\n'` – user2561747 Jan 17 '20 at 02:18
108

You could use tr, like this:

tr " " .

Example:

# echo "hello world" | tr " " .
hello.world

From man tr:

DESCRIPTION
     Translate, squeeze, and/or delete characters from standard input, writ‐ ing to standard output.

aioobe
  • 413,195
  • 112
  • 811
  • 826
  • 1
    While this works for the question as it was asked, it's less general than the accepted answer (which works on character replacement and also arbitrary strings), and it also involves and external command. – Dan Dascalescu Oct 15 '17 at 01:09
  • 10
    On the other hand it works on a 2gb file without loading the entire thing into memory. – aioobe Oct 15 '17 at 05:23
  • The question was about "a string in bash", not arbitrarily large files. – Dan Dascalescu Oct 15 '17 at 10:48
  • 3
    This one has another advantage, we don't need to define variables and can easily use it in bash commands. – Ricardo Barroso Sep 16 '21 at 08:55
72

In bash, you can do pattern replacement in a string with the ${VARIABLE//PATTERN/REPLACEMENT} construct. Use just / and not // to replace only the first occurrence. The pattern is a wildcard pattern, like file globs.

string='foo bar qux'
one="${string/ /.}"     # sets one to 'foo.bar qux'
all="${string// /.}"    # sets all to 'foo.bar.qux'
Gilles 'SO- stop being evil'
  • 104,111
  • 38
  • 209
  • 254
38

Try this

 echo "hello world" | sed 's/ /./g' 
Rob
  • 1,235
  • 2
  • 19
  • 44
12

Use parameter substitution:

string=${string// /.}
Fritz G. Mehner
  • 16,550
  • 2
  • 34
  • 41
8

Try this for paths:

echo \"hello world\"|sed 's/ /+/g'|sed 's/+/\/g'|sed 's/\"//g'

It replaces the space inside the double-quoted string with a + sing, then replaces the + sign with a backslash, then removes/replaces the double-quotes.

I had to use this to replace the spaces in one of my paths in Cygwin.

echo \"$(cygpath -u $JAVA_HOME)\"|sed 's/ /+/g'|sed 's/+/\\/g'|sed 's/\"//g'
serenesat
  • 4,611
  • 10
  • 37
  • 53
dsrdakota
  • 2,415
  • 1
  • 15
  • 10
  • 2
    There is already a two-year old answer that solves the problem with `sed`. The quotes are irrelevant. – chepner May 22 '13 at 19:07
4

The recommended solution by shellcheck would be the following:

string="Hello World" ; echo "${string// /.}"
output: Hello.World

Juliano Costa
  • 2,175
  • 2
  • 18
  • 30