在Bash中替换一个字符为另一个字符

313

我需要在bash中将字符串中的空格( )替换为点号(.)。

我认为这应该很简单,但是我是新手,无法想出如何修改类似的示例以实现此用途。

7个回答

539

7
当处理短字符串时(我猜这是常见情况),使用这种方法很好,但当涉及长字符串时,人们可能更喜欢使用 tr。在我的系统上,当字符串长度超过 1000 个字符时,tr 的性能优于 bash。似乎 bash 的时间复杂度比线性更差。进行了一个小测试:x = "$(tr -dc 'a-z \ n' </dev/urandom | head -c1M)"; time y = "$(tr' ' \\- <<<"$x")"; time z ="$ {x // /-}"。对于长度为1M(=2 ^ 20)的字符串,tr 花费了 0.04s,而 bash 5.0.11 花费了 17s。对于长度为2M的字符串,tr 花费了 0.07s(预期值),而 bash 花费了 69s(随着字符串长度加倍,时间变为原来的4倍)。 - Socowi
1
@Socowi 在变量中存储1Mb并不是很常见的操作!在超过10Kb的情况下,Bash似乎比分叉到“tr”更快!这取决于可用的内存和硬件资源...但你是对的:根据要执行的任务类型,专用工具更有效率! - F. Hauri - Give Up GitHub
对于转义字符,例如换行符,请确保搜索 $'\n' - user2561747

111
你可以使用tr来实现,例如:
tr " " .

例子:

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

来自man tr

描述
     将标准输入中的字符进行翻译、挤压或删除,并写入标准输出。


1
尽管这样做可以回答所问的问题,但它比被接受的答案(该答案适用于字符替换和任意字符串)要不够通用,并且还涉及外部命令。 - Dan Dascalescu
10
另一方面,它可以在不将整个2GB文件加载到内存中的情况下运行。 - aioobe
问题是关于“bash中的字符串”,而不是任意大的文件。 - Dan Dascalescu
3
这个有另一个优点,我们不需要定义变量就可以在bash命令中轻松使用它。 - Ricardo Barroso

73
在bash中,您可以使用${VARIABLE//PATTERN/REPLACEMENT}构造在字符串中执行pattern replacement。仅使用/而不是//只替换第一个出现的匹配项。该模式是通配符模式,就像文件通配符。
string='foo bar qux'
one="${string/ /.}"     # sets one to 'foo.bar qux'
all="${string// /.}"    # sets all to 'foo.bar.qux'

38

试一下这个

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

12
使用参数替换:
string=${string// /.}

8

对于路径,请尝试以下操作:

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

它会将双引号内的空格替换为加号(+), 然后将加号替换为反斜杠, 最后删除/替换双引号。我曾在Cygwin路径中使用它来替换空格。
echo \"$(cygpath -u $JAVA_HOME)\"|sed 's/ /+/g'|sed 's/+/\\/g'|sed 's/\"//g'

2
已经有一个两年前的答案解决了使用 sed 的问题。引号是无关紧要的。 - chepner

4
shellcheck 推荐的解决方案如下所示: string="Hello World" ; echo "${string// /.}"
输出结果: Hello.World

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接