Jak mogę uzyskać bash / zsh, aby zmienić tekst z „foo.foo.foo” na „foo foo foo” za pomocą skryptu / aliasu?

11

Mogę być może używać <albo >albo |. Może muszę użyć grep?

KDG
źródło
2
Co rozumiesz przez tekst? plik lub tekst w pliku? echo "foo.foo.foo" | sed 's/\./ /g'
Zanna,
1
@KDG i) musisz utworzyć osobne konto dla każdej witryny SE, ale jeśli użyjesz tych samych danych logowania, konta zostaną połączone. ii) Chociaż ta strona jest rzeczywiście ograniczona wyłącznie do Ubuntu, nie widzę tutaj niczego, co stanowiłoby niezbity dowód, że nie używasz Ubuntu, więc nie widzę też powodu, aby ją zamykać.
terdon

Odpowiedzi:

20

Możesz utworzyć funkcję i dodać na końcu swojego ~/.bashrc, na przykład:

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

przykład użycia:

$ nodot foo.foo.foo
foo foo foo

Możesz użyć tej funkcji również w zsh, po prostu dodaj do niej ~/.zshrc.

Zanna
źródło
6
@tbodt zmiana zaakceptowanej odpowiedzi w celu całkowitego zastąpienia jej inną aktualną odpowiedzią po prostu nie jest wykonywana.
mur
28

Możesz użyć polecenia tr do konwersji znaków.

% echo "foo.foo.foo" | tr '.' ' ' 
foo foo foo
Validus Oculus
źródło
fajne wskazówki nigdy wcześniej nie słyszały o „tr”
KDG
6
trjest właściwie przeznaczony właśnie do tego celu. sedto przesada.
Max Ried
1
+1 za tr, co jest bardzo przydatnym narzędziem, o którym wiele osób nie wie z jakiegoś powodu. O wiele prostsze niż w sedprzypadku konwertowania całych klas znaków.
puszysty
5
Nigdy nie pisz tego w „C”, jeśli możesz to zrobić w „awk”; Nigdy nie rób tego w „awk”, jeśli „sed” sobie z tym poradzi; Nigdy nie używaj „sed”, gdy „tr” może wykonać zadanie; Nigdy nie wzywaj „tr”, gdy „kot” jest wystarczający; Jeśli to możliwe, unikaj używania „kota”. - Zasady programowania Taylora
Ross Presser,
1
Niezła odpowiedź. Ta odpowiedź powinna zostać zaakceptowana.
SuB
24

Używając czystej bash:

bash-3.2$ a='a.a.a'
bash-3.2$ echo "${a/./ }"
a a.a
bash-3.2$ echo "${a//./ }"
a a a
muru
źródło
9

Za pomocą Internal Field Separator (IFS)zmiennej:

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

Można to ładnie włączyć w funkcję:

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
}

I działaj tak:

bash-4.3$ split_dot "foo.baz.bar"                                                                             
foo baz bar
Sergiy Kolodyazhnyy
źródło
3
Resetowanie IFSjest trudniejsze niż zapisanie go w zmiennej i przywrócenie wartości. Rozbrojone IFSi puste IFSmają inne zachowanie, więc musisz sprawdzić, czy jest rozbrojone, czy tylko puste, na wypadek gdyby wcześniej było puste.
muru
5
Funkcje nie działają w podpowłokach. Tylko niektóre zmienne mają inny zakres (parametry pozycyjne i kilka innych wymienionych w gnu.org/software/bash/manual/html_node/Shell-Functions.html ). Właśnie dlatego mamy localsłowo kluczowe.
mur
3
Więc jeśli OP IFSz jakiegoś powodu wcześniej się rozbroił, ta funkcja ustawiłaby go na pusty, co ma inne zachowanie.
mur
2
@fedorqui niestety nawet to nie zadziała; ponieważ wartość IFS jest ustawiona zbyt późno, aby można było przeanalizować bieżącą instrukcję. Będziesz musiał użyć podpowłoki (IFS=.; echo ...). Ponieważ w tej odpowiedzi użyto funkcji, Serg mógł po prostu zmienić nawiasy klamrowe w nawiasy i nie martwić się zresetowaniem IFS
muru
2
@fedorqui, możesz znaleźć moje podobne pytanie na temat U&L: unix.stackexchange.com/q/264635/70524 (Gilles zawsze daje bardzo dobre odpowiedzi)
mur
4

Ktoś przegapił 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
heemayl
źródło
1

Można xargsrównież użyć . Oto użycie jednej linijkixargs

$ echo "foo.foo.foo" | xargs -d .
foo foo foo
souravc
źródło