26

假设我有一个字符串,$str。我希望编辑 $str 以便将其中的所有空格都替换为下划线。

例子

a="hello world"

我想要的最终输出

echo "$a"

成为hello_world

4

5 回答 5

57

您可以尝试以下方法:

str="${str// /_}"
于 2013-10-29T14:44:48.490 回答
17
$ a="hello world"
$ echo ${a// /_}
hello_world

根据 bash(1):

${parameter/pattern/string}

模式替换。该模式被扩展以产生一个模式,就像在路径名扩展中一样。参数被扩展,模式与其值的最长匹配被替换为字符串。如果 pattern 以 / 开头,则替换所有匹配的 pattern
用字符串。通常只替换第一场比赛。如果pattern以#开头,则必须匹配参数扩展值的开头。如果模式以 % 开头,它必须匹配参数扩展值的末尾。如果 string 为 null,则删除 pattern 的匹配项,并且可以省略 / 后面的 pattern。如果参数是@或*,则依次对每个位置参数应用替换操作,展开是结果列表。如果 parameter 是下标为 @ 或 * 的数组变量,则对数组的每个成员依次进行替换操作,展开是结果列表。

于 2013-10-29T14:40:50.643 回答
12

纯重击:

a="hello world"
echo "${a// /_}"

或 tr:

tr -s ' ' '_' <<< "$a"
于 2013-10-29T14:41:45.443 回答
6

直接从sed变量中读取:

$ sed 's/ /_/g' <<< "$a"
hello_world

要存储结果,您必须使用以下var=$(command)语法:

a=$(sed 's/ /_/g' <<< "$a")

为了完整起见,awk可以这样做:

$ 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
于 2013-10-29T14:40:21.093 回答
2

多个空格到一个下划线

这可以通过GNU shell 参数扩展轻松实现。尤其是:

${parameter/pattern/string}

如果 pattern 以 开头/,则所有匹配的 pattern 都被替换为 string。

+(pattern-list)

匹配给定模式的一次或多次出现。

因此:

$ a='hello world    example'

$ echo ${a// /_}
hello_world____example

$ echo ${a//+( )/_}
hello_world_example

但是,要使其在 bash 脚本中工作,需要进行两项修改:

  1. 参数扩展需要用双引号封装," "防止输入字段分隔符 $IFS分词。
  2. extglob需要使用 builtin 启用 shell 选项,shopt以便识别扩展的模式匹配运算符。

bash 脚本最终如下所示:

#!/usr/bin/env bash
shopt -s extglob
a='hello world    example'
echo "${a//+( )/_}"
于 2021-02-24T13:31:15.007 回答