Wie kann ich bash / zsh dazu bringen, Text mit einem Skript / Alias ​​von "foo.foo.foo" in "foo foo foo" zu ändern?


11

Ich kann vielleicht <oder >oder verwenden |. Vielleicht muss ich grep verwenden?


2
Was meinst du mit einem Text? eine Datei oder ein Text in einer Datei? echo "foo.foo.foo" | sed 's/\./ /g'
Zanna

1
@KDG i) Sie müssen für jede SE-Site ein separates Konto erstellen. Wenn Sie jedoch dieselben Anmeldeinformationen verwenden, werden die Konten verknüpft. ii) Obwohl diese Seite in der Tat ausschließlich auf Ubuntu beschränkt ist, sehe ich hier nichts, was einen unwiderlegbaren Beweis dafür darstellen würde, dass Sie Ubuntu nicht verwenden. Daher sehe ich auch keinen Grund, sie zu schließen.
Terdon

Antworten:


20

Sie können eine Funktion erstellen und am Ende Ihrer hinzufügen ~/.bashrc, zum Beispiel:

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

Anwendungsbeispiel:

$ nodot foo.foo.foo
foo foo foo

Sie können diese Funktion auch in zsh ~/.zshrcverwenden. Fügen Sie stattdessen einfach Ihre hinzu .


6
@tbodt Das Ändern einer akzeptierten Antwort, um sie vollständig durch eine andere aktuelle Antwort zu ersetzen, wird einfach nicht durchgeführt.
Muru

28

Sie können den Befehl tr verwenden , um Zeichen zu konvertieren.

% echo "foo.foo.foo" | tr '.' ' ' 
foo foo foo

coole tipps hören noch nie von "tr"
KDG

6
trist eigentlich genau für diesen Zweck gedacht. sedist übertrieben.
Max Ried

1
+1 genau für tr, was ein sehr nützliches Werkzeug ist, von dem viele Leute aus irgendeinem Grund nichts zu wissen scheinen. Viel einfacher als sedzum Konvertieren ganzer Zeichenklassen.
flauschige

5
Schreiben Sie es niemals in 'C', wenn Sie es in 'awk' tun können. Mach es niemals in 'awk', wenn 'sed' damit umgehen kann; Verwenden Sie niemals 'sed', wenn 'tr' die Arbeit erledigen kann. Rufen Sie niemals 'tr' auf, wenn 'cat' ausreicht. Vermeiden Sie nach Möglichkeit die Verwendung von "Katze". - Taylors Programmiergesetze
Ross Presser

1
Gute Antwort. Diese Antwort sollte akzeptiert werden.
SuB

24

Mit reinem Bash:

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

9

Mit 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

Dies kann gut in eine Funktion eingefügt werden:

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
}

Und lauf so:

bash-4.3$ split_dot "foo.baz.bar"                                                                             
foo baz bar

3
Das Zurücksetzen IFSist schwieriger als nur das Speichern in einer Variablen und das Wiederherstellen des Werts. Ein nicht gesetztes IFSund ein leeres IFSVerhalten haben ein unterschiedliches Verhalten. Sie müssen daher überprüfen, ob es nicht gesetzt oder nur leer ist, falls es zuvor leer war.
Muru

5
Funktionen werden nicht in Unterschalen ausgeführt. Nur einige Variablen haben einen anderen Bereich (die Positionsparameter und einige andere sind in gnu.org/software/bash/manual/html_node/Shell-Functions.html aufgeführt ). Deshalb haben wir das localSchlüsselwort.
Muru

3
Wenn OP zuvor IFSaus irgendeinem Grund deaktiviert worden wäre, würde diese Funktion es auf leer setzen, was ein anderes Verhalten aufweist.
Muru

2
@fedorqui leider funktioniert auch das nicht; da der IFS-Wert für die zu analysierende aktuelle Anweisung zu spät eingestellt ist. Sie müssten tatsächlich eine Unterschale verwenden (IFS=.; echo ...). Da diese Antwort eine Funktion verwendete, konnte Serg einfach die geschweiften Klammern in Klammern ändern und sich keine Gedanken über das Zurücksetzen von IFS machen
Muru

2
@ Fedorqui Sie könnten meine ähnliche Frage auf U & L interessant finden: unix.stackexchange.com/q/264635/70524 (Gilles gibt immer sehr gute Antworten)
Muru

4

Wer verpasst 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

Man kann xargsauch verwenden. Hier ist ein Einzeiler mitxargs

$ echo "foo.foo.foo" | xargs -d .
foo foo foo
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.