I can maybe use <
or >
or |
. Maybe I need to use grep?
6 Answers
You can use tr command to convert character.
% echo "foo.foo.foo" | tr '.' ' '
foo foo foo
-
-
6
-
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 thansed
for converting entire classes of characters.– fluffyNov 19, 2016 at 22:37 -
5Never 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 Nov 20, 2016 at 6:01
-
1
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
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.
-
6@tbodt changing an accepted answer to completely replace it with another current answer is simply not done.– muruNov 21, 2016 at 2:27
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
-
3Resetting
IFS
is a more tricky than just saving it to a variable and restoring the value. An unsetIFS
and an emptyIFS
have different behaviour, so you need to check whether it is unset or just empty, in case it was empty before.– muruNov 19, 2016 at 14:56 -
5Functions 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.– muruNov 19, 2016 at 15:02 -
3So if OP had unset
IFS
for some reason previously, this function would set it to empty, which does have different behaviour.– muruNov 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– muruNov 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)– muruNov 19, 2016 at 15:30
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
One can use xargs
also. Here is a one-liner using xargs
$ echo "foo.foo.foo" | xargs -d .
foo foo foo
echo "foo.foo.foo" | sed 's/\./ /g'