在 Bash 中用另一个字符替换一个字符
Posted
技术标签:
【中文标题】在 Bash 中用另一个字符替换一个字符【英文标题】:Replace one character with another in Bash 【发布时间】:2011-08-21 03:40:03 【问题描述】:我需要在 bash 中将字符串中的空格 (
) 替换为点 (.
)。
我认为这会很简单,但我是新手,所以我不知道如何修改类似的示例。
【问题讨论】:
【参考方案1】:使用内联 shell 字符串替换。示例:
foo=" "
# replace first blank only
bar=$foo/ /.
# replace all blanks
bar=$foo// /.
更多详情请见http://tldp.org/LDP/abs/html/string-manipulation.html。
【讨论】:
虽然这个解决方案在处理短字符串时很好(我猜是常见的情况),但对于长字符串,可能更喜欢tr
。在我的系统上,tr
的性能优于 bash,它从超过 1000
字符的字符串开始。似乎 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 玩存储在变量中的 1Mb 并不常见!超过 10Kb,bash 似乎比 fork 到 tr
更快!...取决于可用的内存和硬件资源...但你是对的!:根据要做的工作,专用工具保持更高效!
对于换行符等转义字符,请务必搜索$'\n'
【参考方案2】:
你可以使用tr
,像这样:
tr " " .
例子:
# echo "hello world" | tr " " .
hello.world
来自man tr
:
描述 翻译、压缩和/或删除标准输入中的字符,写 到标准输出。
【讨论】:
虽然这适用于所提出的问题,但它不如公认的答案通用(适用于字符替换和任意字符串),它还涉及外部命令。 另一方面,它适用于 2gb 文件,无需将整个文件加载到内存中。 问题是关于“bash 中的字符串”,而不是任意大的文件。 这个还有一个好处,我们不需要定义变量,可以很方便的在bash命令中使用。【参考方案3】:在 bash 中,您可以使用 $VARIABLE//PATTERN/REPLACEMENT
构造在字符串中执行 pattern replacement。仅使用 /
而不是 //
仅替换第一个匹配项。该模式是通配符模式,如文件 glob。
string='foo bar qux'
one="$string/ /." # sets one to 'foo.bar qux'
all="$string// /." # sets all to 'foo.bar.qux'
【讨论】:
【参考方案4】:试试这个
echo "hello world" | sed 's/ /./g'
【讨论】:
【参考方案5】:使用参数替换:
string=$string// /.
【讨论】:
【参考方案6】:试试这个路径:
echo \"hello world\"|sed 's/ /+/g'|sed 's/+/\/g'|sed 's/\"//g'
它将双引号字符串中的空格替换为 +
sing,然后将 +
符号替换为反斜杠,然后删除/替换双引号。
我不得不用它来替换我在 Cygwin 中的一条路径中的空格。
echo \"$(cygpath -u $JAVA_HOME)\"|sed 's/ /+/g'|sed 's/+/\\/g'|sed 's/\"//g'
【讨论】:
已经有一个两年前的答案可以解决sed
的问题。引号无关紧要。【参考方案7】:
shellcheck 推荐的解决方案如下:
string="Hello World" ; echo "$string// /."
output: Hello.World
【讨论】:
以上是关于在 Bash 中用另一个字符替换一个字符的主要内容,如果未能解决你的问题,请参考以下文章