小智 28

您可以使用tr命令来转换字符。

% echo "foo.foo.foo" | tr '.' ' ' 
foo foo foo
Run Code Online (Sandbox Code Playgroud)

  • `tr` 实际上就是为了这个目的。`sed` 是矫枉过正。 (6认同)
  • 如果你能用 'awk' 写,就不要用 'C' 写;如果 'sed' 可以处理的话,永远不要在 'awk' 中这样做;当“tr”可以完成这项工作时,切勿使用“sed”;当 'cat' 足够时,永远不要调用 'tr';尽可能避免使用“cat”。——泰勒编程定律 (5认同)

mur*_*uru 24

使用纯 bash:

bash-3.2$ a='a.a.a'
bash-3.2$ echo "${a/./ }"
a a.a
bash-3.2$ echo "${a//./ }"
a a a
Run Code Online (Sandbox Code Playgroud)


Zan*_*nna 20

您可以创建一个函数并添加到您的末尾~/.bashrc,例如:

nodot() {  echo "$1" | sed 's/\./ /g' ; }
Run Code Online (Sandbox Code Playgroud)

用法示例:

$ nodot foo.foo.foo
foo foo foo
Run Code Online (Sandbox Code Playgroud)

您也可以在 zsh 中使用此功能,只需添加到您的即可~/.zshrc

  • @tbodt 更改已接受的答案以将其完全替换为另一个当前答案根本没有完成。 (6认同)

Ser*_*nyy 9

使用Internal Field Separator (IFS)变量:

bash-4.3$ old_ifs=$IFS
bash-4.3$ IFS="."
bash-4.3$ var="foo.foo.foo"
bash-4.3$ echo $var
foo foo foo
bash-4.3$ IFS=$old_ifs
Run Code Online (Sandbox Code Playgroud)

这可以很好地放入一个函数中:

split_dot()
{

    string="$1"

    if set | grep -q "IFS";
    then
       ifs_unset="false"
       old_ifs=$IFS
    else
       ifs_unset="true"
    fi

    IFS="."
    echo $string
    if [ "$ifs_unset" == "true" ];
    then
       unset IFS
    else
       IFS=$old_ifs
    fi
}
Run Code Online (Sandbox Code Playgroud)

并运行:

bash-4.3$ split_dot "foo.baz.bar"                                                                             
foo baz bar
Run Code Online (Sandbox Code Playgroud)

  • 函数不在子shell 中运行。只有一些变量具有不同的范围(位置参数,以及 https://www.gnu.org/software/bash/manual/html_node/Shell-Functions.html 中列出的其他一些变量)。这就是为什么我们有 `local` 关键字。 (5认同)
  • 重置“IFS”比将其保存到变量并恢复值更棘手。未设置的 `IFS` 和空的 `IFS` 具有不同的行为,因此您需要检查它是未设置还是只是空的,以防它之前是空的。 (3认同)
  • 因此,如果 OP 之前出于某种原因取消了 `IFS` 设置,该函数会将其设置为空,这确实具有不同的行为。 (3认同)
  • @fedorqui 不幸的是,即使那样也行不通;因为 IFS 值对于正在解析的当前语句设置得太晚了。您实际上必须使用子shell `(IFS=.; echo ...)`。由于这个答案使用了一个函数,Serg 可以将大括号更改为括号,而根本不用担心重置 IFS (2认同)
  • @fedorqui 你可能会发现我在 U&L 上的类似问题很有趣:http://unix.stackexchange.com/q/264635/70524(Gilles 总是给出很好的答案) (2认同)