11

I can maybe use < or > or |. Maybe I need to use grep?

2
  • 2
    What do you mean by a text? a file or some text in a file? echo "foo.foo.foo" | sed 's/\./ /g'
    – Zanna
    Commented Nov 19, 2016 at 9:48
  • 1
    @K.D.G i) you need to create a separate account for each SE site, but if you use the same credentials, the accounts will be linked. ii) While this site is indeed limited to Ubuntu exclusively, I don't see anything here that would be irrefutable proof that you are not using Ubuntu, so I also se no reason to close it.
    – terdon
    Commented Nov 19, 2016 at 14:30

6 Answers 6

28

You can use tr command to convert character.

% echo "foo.foo.foo" | tr '.' ' ' 
foo foo foo
6
  • cool tips never hear of "tr" before
    – K.D.G
    Commented Nov 19, 2016 at 13:41
  • 6
    tr is actually meant for exactly this purpose. sed is overkill.
    – bot47
    Commented Nov 19, 2016 at 15:06
  • 1
    +1 precisely for tr, which is a very useful tool that a lot of people don't seem to know about for some reason. Way simpler than sed for converting entire classes of characters.
    – fluffy
    Commented Nov 19, 2016 at 22:37
  • 5
    Never write it in 'C' if you can do it in 'awk'; Never do it in 'awk' if 'sed' can handle it; Never use 'sed' when 'tr' can do the job; Never invoke 'tr' when 'cat' is sufficient; Avoid using 'cat' whenever possible. --Taylor's Laws of Programming Commented Nov 20, 2016 at 6:01
  • 1
    Nice answer. This answer should be accepted.
    – SuB
    Commented Nov 20, 2016 at 20:56
24

Using pure bash:

bash-3.2$ a='a.a.a'
bash-3.2$ echo "${a/./ }"
a a.a
bash-3.2$ echo "${a//./ }"
a a a
20

You can make a function and add to the end of your ~/.bashrc, for example:

nodot() {  echo "$1" | sed 's/\./ /g' ; }

usage example:

$ nodot foo.foo.foo
foo foo foo

You can use this function in zsh too, just add to your ~/.zshrc instead.

1
  • 6
    @tbodt changing an accepted answer to completely replace it with another current answer is simply not done.
    – muru
    Commented Nov 21, 2016 at 2:27
9

Using Internal Field Separator (IFS) variable:

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

This can be put nicely into a function:

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
}

And run as so:

bash-4.3$ split_dot "foo.baz.bar"                                                                             
foo baz bar
11
  • 3
    Resetting IFS is a more tricky than just saving it to a variable and restoring the value. An unset IFS and an empty IFS have different behaviour, so you need to check whether it is unset or just empty, in case it was empty before.
    – muru
    Commented Nov 19, 2016 at 14:56
  • 5
    Functions don't run in subshells. Only some variables have different scope (the positional parameters, and a few others in listed in gnu.org/software/bash/manual/html_node/Shell-Functions.html). That's why we have the local keyword.
    – muru
    Commented Nov 19, 2016 at 15:02
  • 3
    So if OP had unset IFS for some reason previously, this function would set it to empty, which does have different behaviour.
    – muru
    Commented Nov 19, 2016 at 15:03
  • 2
    @fedorqui unfortunately even that won't work; since the IFS value is set too late for the current statement being parsed. You'd actually have to use a subshell (IFS=.; echo ...). Since this answer used a function, Serg could just change the braces to parentheses and not worry about resetting IFS at all
    – muru
    Commented Nov 19, 2016 at 15:15
  • 2
    @fedorqui you might find my similar question on U&L interesting: unix.stackexchange.com/q/264635/70524 (Gilles always gives very good answers)
    – muru
    Commented Nov 19, 2016 at 15:30
4

Anyone missed awk/perl/python/go:


% awk '{gsub(/[.]/, " ", $0); print}' <<<'foo.foo.foo'                      
foo foo foo

% perl -pe 's/\./ /g' <<<'foo.foo.foo'                                      
foo foo foo

% python -c 'import sys; print sys.stdin.read().replace(".", " ")' <<<'foo.foo.foo'
foo foo foo

% cat input.go
package main

import (
    "os"
    "strings"
    "fmt"
)

func main () {
    args := os.Args
    if len(args) != 2 {
        fmt.Println("Not enough arguments")
        return
    }
    out := strings.Replace(args[1], ".", " ", -1)
    fmt.Println(out)
}

% go run input.go 'foo.foo.foo' 
foo foo foo
1

One can use xargs also. Here is a one-liner using xargs

$ echo "foo.foo.foo" | xargs -d .
foo foo foo

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .