ChatGPT解决这个技术问题 Extra ChatGPT

Replace one character with another in Bash

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.


B
Brian Clapper

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.


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' </dev/urandom | head -c1M)"; time y="$(tr ' ' \\- <<< "$x")"; time z="${x// /-}". With a string length of 1M (=2^20) tr took 0.04s and bash 5.0.11 took 17s. With 2M tr took 0.07s (expected) but bash took 69s (4 times as long for twice the string length).
@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!
For escaped characters like newlines, make sure to search for $'\n'
a
aioobe

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.


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.
On the other hand it works on a 2gb file without loading the entire thing into memory.
The question was about "a string in bash", not arbitrarily large files.
This one has another advantage, we don't need to define variables and can easily use it in bash commands.
G
Gilles 'SO- stop being evil'

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'

R
Rob

Try this

 echo "hello world" | sed 's/ /./g' 

F
Fritz G. Mehner

Use parameter substitution:

string=${string// /.}

s
serenesat

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'

There is already a two-year old answer that solves the problem with sed. The quotes are irrelevant.
J
Juliano Costa

The recommended solution by shellcheck would be the following:

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