Como posso que o bash / zsh mude algum texto de "foo.foo.foo" para "foo foo foo" com um script / alias?


11

Talvez eu possa usar <ou >ou |. Talvez eu precise usar grep?


2
O que você quer dizer com texto? um arquivo ou algum texto em um arquivo? echo "foo.foo.foo" | sed 's/\./ /g'
Zanna

1
@KDG i) você precisa criar uma conta separada para cada site SE, mas se você usar as mesmas credenciais, as contas serão vinculadas. ii) Embora este site seja realmente limitado exclusivamente ao Ubuntu, não vejo nada aqui que seja prova irrefutável de que você não esteja usando o Ubuntu, por isso também não vejo motivo para fechá-lo.
Terdon #

Respostas:


20

Você pode criar uma função e adicionar ao final da sua ~/.bashrc, por exemplo:

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

exemplo de uso:

$ nodot foo.foo.foo
foo foo foo

Você também pode usar esta função no zsh, basta adicionar ao seu ~/.zshrc.


6
@ tbodt alterar uma resposta aceita para substituí-la completamente por outra resposta atual simplesmente não é feito.
Muru

28

Você pode usar o comando tr para converter caracteres.

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

dicas legais que nunca ouviram falar de "tr" antes
KDG 19/11/16

6
tré realmente destinado exatamente para esse propósito. sedé um exagero.
Max Ried

1
+1 exatamente para tr, que é uma ferramenta muito útil que muitas pessoas parecem não conhecer por algum motivo. Muito mais simples do que sedconverter classes inteiras de caracteres.
fluffy

5
Nunca escreva em 'C' se você puder fazê-lo em 'awk'; Nunca faça isso em 'awk' se 'sed' puder lidar com isso; Nunca use 'sed' quando 'tr' puder fazer o trabalho; Nunca chame 'tr' quando 'gato' for suficiente; Evite usar 'gato' sempre que possível. Leis de Programação do --Taylor
Ross Presser

1
Boa resposta. Esta resposta deve ser aceita.
SuB

24

Usando o bash puro:

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

9

Usando a Internal Field Separator (IFS)variável:

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

Isso pode ser bem colocado em uma função:

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
}

E execute da seguinte maneira:

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

3
A redefinição IFSé mais complicada do que apenas salvá-la em uma variável e restaurar o valor. Um unset IFSe um vazio IFStêm um comportamento diferente; portanto, é necessário verificar se está desativado ou apenas vazio, caso estivesse vazio antes.
Muru

5
Funções não são executadas em subcascas. Somente algumas variáveis ​​têm escopo diferente (os parâmetros posicionais e outras listadas em gnu.org/software/bash/manual/html_node/Shell-Functions.html ). É por isso que temos a localpalavra - chave.
Muru

3
Portanto, se o OP tivesse sido desabilitado IFSpor algum motivo anteriormente, essa função o definiria como vazio, o que tem um comportamento diferente.
muru

2
@fedorqui infelizmente, mesmo isso não vai funcionar; já que o valor do IFS é definido muito tarde para a instrução atual ser analisada. Você realmente teria que usar um subshell (IFS=.; echo ...). Desde esta resposta usada uma função, Serg só poderia mudar as chaves para parênteses e não se preocupar sobre como redefinir IFS em tudo
Muru

2
@fedorqui que você pode encontrar a minha pergunta semelhante sobre L & L interessante: unix.stackexchange.com/q/264635/70524 (Gilles sempre dá respostas muito boas)
Muru

4

Alguém perdeu 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

Pode-se usar xargstambém. Aqui está um one-liner usandoxargs

$ echo "foo.foo.foo" | xargs -d .
foo foo foo
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.