Как мне заставить bash / zsh изменить текст с «foo.foo.foo» на «foo foo foo» с помощью сценария / псевдонима?


11

Я могу возможно использовать <или >или |. Может мне нужно использовать grep?


2
Что вы подразумеваете под текстом? файл или какой-то текст в файле? echo "foo.foo.foo" | sed 's/\./ /g'
Занна

1
@KDG i) вам нужно создать отдельную учетную запись для каждого сайта SE, но если вы используете те же учетные данные, учетные записи будут связаны. ii) Хотя этот сайт действительно ограничен исключительно Ubuntu, я не вижу здесь ничего, что могло бы стать неопровержимым доказательством того, что вы не используете Ubuntu, поэтому я также не вижу причин закрывать его.
тердон

Ответы:


20

Вы можете сделать функцию и добавить в конец свой ~/.bashrc, например:

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

пример использования:

$ nodot foo.foo.foo
foo foo foo

Вы также можете использовать эту функцию в zsh, просто добавьте к ней ~/.zshrc.


6
@tbodt изменение принятого ответа, чтобы полностью заменить его другим текущим ответом, просто не сделано.
Муру

28

Вы можете использовать команду tr для преобразования символов.

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

классные советы никогда не слышали о "tr" раньше
KDG

6
trна самом деле предназначен именно для этой цели. sedэто перебор.
Макс Рид

1
+1 именно для tr, что является очень полезным инструментом, о котором многие люди, кажется, не знают по какой-то причине. Гораздо проще, чем sedдля преобразования целых классов символов.
пушистый

5
Никогда не пишите это в 'C', если вы можете сделать это в 'awk'; Никогда не делайте это в «awk», если «sed» может с этим справиться; Никогда не используйте «sed», когда «tr» может сделать работу; Никогда не вызывайте 'tr', когда достаточно 'cat'; Старайтесь не использовать «кошку», когда это возможно. - Законы программирования
Тейлора

1
Хороший ответ. Этот ответ должен быть принят.
Суббота

24

Используя чистый 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

Используя Internal Field Separator (IFS)переменную:

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

Это можно поместить в функцию:

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
}

И беги так:

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

3
Сброс IFSявляется более сложным, чем просто сохранить его в переменной и восстановить значение. Unset IFSи empty IFSимеют разное поведение, поэтому вам нужно проверить, является ли он unset или просто пустым, на случай, если раньше он был пустым.
Муру

5
Функции не работают в подоболочках. Только некоторые переменные имеют различную область действия (позиционные параметры, а некоторые другие перечислены в gnu.org/software/bash/manual/html_node/Shell-Functions.html ). Вот почему у нас есть localключевое слово.
Муру

3
Таким образом, если бы ранее IFSпо какой-либо причине OP был сброшен , эта функция установила бы его пустым, что ведет себя по-разному.
Муру

2
@fedorqui, к сожалению, даже это не сработает; поскольку значение IFS установлено слишком поздно для анализа текущего оператора. Вы бы на самом деле должны использовать подоболочку (IFS=.; echo ...). Поскольку в этом ответе использовалась функция, Серг мог просто заменить скобки на круглые скобки и вообще не беспокоиться о сбросе IFS
Muru

2
@fedorqui, вы могли бы найти мой похожий вопрос по U & L интересным: unix.stackexchange.com/q/264635/70524 (Жиль всегда дает очень хорошие ответы)
muru

4

Кто-нибудь пропустил 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

Можно xargsтакже использовать . Вот однострочник, использующийxargs

$ echo "foo.foo.foo" | xargs -d .
foo foo foo
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.