Comment puis-je demander à bash / zsh de changer du texte de "foo.foo.foo" en "foo foo foo" avec un script / alias?

11

Je peux peut-être utiliser <ou >ou |. Peut-être que je dois utiliser grep?

KDG
la source
2
Qu'entendez-vous par un texte? un fichier ou du texte dans un fichier? echo "foo.foo.foo" | sed 's/\./ /g'
Zanna
1
@KDG i) vous devez créer un compte distinct pour chaque site SE, mais si vous utilisez les mêmes informations d'identification, les comptes seront liés. ii) Bien que ce site soit en effet limité à Ubuntu exclusivement, je ne vois rien ici qui serait une preuve irréfutable que vous n'utilisez pas Ubuntu, donc je ne vois aucune raison de le fermer.
terdon

Réponses:

20

Vous pouvez créer une fonction et ajouter à la fin de votre ~/.bashrc, par exemple:

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

exemple d'utilisation:

$ nodot foo.foo.foo
foo foo foo

Vous pouvez également utiliser cette fonction dans zsh, ajoutez-la simplement à votre ~/.zshrcplace.

Zanna
la source
6
@tbodt changer une réponse acceptée pour la remplacer complètement par une autre réponse actuelle n'est tout simplement pas fait.
muru
28

Vous pouvez utiliser la commande tr pour convertir le caractère.

% echo "foo.foo.foo" | tr '.' ' ' 
foo foo foo
Validus Oculus
la source
conseils cool jamais entendu parler de "tr" avant
KDG
6
trest en fait destiné exactement à cet effet. sedest exagéré.
Max Ried
1
+1 précisément pour tr, qui est un outil très utile que beaucoup de gens ne semblent pas connaître pour une raison quelconque. Bien plus simple que sedpour convertir des classes entières de caractères.
moelleux
5
Ne l'écrivez jamais en «C» si vous pouvez le faire en «awk»; Ne le faites jamais en «awk» si «sed» peut le gérer; N'utilisez jamais «sed» lorsque «tr» peut faire le travail; N'invoquez jamais «tr» lorsque «chat» est suffisant; Évitez autant que possible d'utiliser «chat». - Lois de programmation de Taylor
Ross Presser
1
Bonne réponse. Cette réponse doit être acceptée.
SuB
24

Utilisation de bash pur:

bash-3.2$ a='a.a.a'
bash-3.2$ echo "${a/./ }"
a a.a
bash-3.2$ echo "${a//./ }"
a a a
muru
la source
9

Utilisation de 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

Cela peut être joliment mis dans une fonction:

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
}

Et exécutez comme suit:

bash-4.3$ split_dot "foo.baz.bar"                                                                             
foo baz bar
Sergiy Kolodyazhnyy
la source
3
La réinitialisation IFSest plus délicate que de simplement l'enregistrer dans une variable et de restaurer la valeur. Un non défini IFSet un vide IFSont un comportement différent, vous devez donc vérifier s'il est non défini ou simplement vide, au cas où il était vide auparavant.
muru
5
Les fonctions ne s'exécutent pas en sous-coquilles. Seules certaines variables ont une portée différente (les paramètres de position et quelques autres sont répertoriés dans gnu.org/software/bash/manual/html_node/Shell-Functions.html ). C'est pourquoi nous avons le localmot - clé.
muru
3
Donc, si OP avait déjà été désactivé IFSpour une raison quelconque, cette fonction le mettrait à vide, ce qui a un comportement différent.
muru
2
@fedorqui malheureusement, même cela ne fonctionnera pas; car la valeur IFS est définie trop tard pour que l'instruction en cours soit analysée. Il faudrait en fait utiliser un sous-shell (IFS=.; echo ...). Puisque cette réponse utilisait une fonction, Serg pourrait simplement changer les accolades en parenthèses et ne pas s'inquiéter de réinitialiser IFS du tout
muru
2
@fedorqui vous pourriez trouver ma question similaire sur U&L intéressante: unix.stackexchange.com/q/264635/70524 (Gilles donne toujours de très bonnes réponses)
muru
4

Quelqu'un a manqué 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
la source
1

On peut xargsaussi utiliser . Voici un one-liner utilisantxargs

$ echo "foo.foo.foo" | xargs -d .
foo foo foo
souravc
la source