Как я могу получить bash / zsh, чтобы изменить некоторый текст из “ foo.foo.foo ” to “ foo foo foo ” со сценарием / псевдонимом?

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

1
задан 19 November 2016 в 14:16

5 ответов

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

% echo "foo.foo.foo" | tr '.' ' ' 
foo foo foo
28
ответ дан 23 May 2018 в 04:04
  • 1
    крутые подсказки никогда не слышат о " tr " до – K.D.G 19 November 2016 в 17:41
  • 2
    tr на самом деле предназначен именно для этой цели. sed является излишним. – Max Ried 19 November 2016 в 19:06
  • 3
    +1 точно для tr, что является очень полезным инструментом, о котором многие люди, похоже, почему-то не знают. Путь проще, чем sed для преобразования целых классов символов. – fluffy 20 November 2016 в 02:37
  • 4
    Никогда не записывайте его в «C», если вы можете сделать это в «awk»; Никогда не делайте это в awk, если «sed» может справиться с этим; Никогда не используйте «sed», когда «tr» может выполнять эту работу; Никогда не вызывайте «tr», когда «cat» достаточно; Избегайте использования «кошки», когда это возможно. - Законы программирования Тейлора – Ross Presser 20 November 2016 в 10:01
  • 5
    Хороший ответ. Этот ответ должен быть принят. – SuB 21 November 2016 в 00:56

Использование чистого bash:

bash-3.2$ a='a.a.a'
bash-3.2$ echo "${a/./ }"
a a.a
bash-3.2$ echo "${a//./ }"
a a a
25
ответ дан 23 May 2018 в 04:04

Использование переменной 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
9
ответ дан 23 May 2018 в 04:04
  • 1
    Сброс IFS более сложный, чем просто сохранение его переменной и восстановление значения. Неисправленные IFS и пустые IFS имеют другое поведение, поэтому вам нужно проверить, не является ли он незавершенным или просто пустым, если он был пуст раньше. – muru 19 November 2016 в 18:56
  • 2
    Функции не выполняются в подоболочках. Только некоторые переменные имеют разную область (позиционные параметры и некоторые другие, перечисленные в gnu.org/software/bash/manual/html_node/Shell-Functions.html ). Вот почему у нас есть ключевое слово local. – muru 19 November 2016 в 19:02
  • 3
    Так что если OP ранее отключился IFS, эта функция установила бы его пустым, что имеет другое поведение. – muru 19 November 2016 в 19:03
  • 4
    @fedorqui, к сожалению, даже это не сработает; поскольку значение IFS установлено слишком поздно для анализа текущего оператора. Вы действительно должны использовать подоболочку (IFS=.; echo ...). Поскольку этот ответ использовал функцию, Серг мог просто изменить фигурные скобки в скобки и не беспокоиться о перезагрузке IFS вообще – muru 19 November 2016 в 19:15
  • 5
    @fedorqui, вы можете найти мой аналогичный вопрос о U & amp; L interesting: unix.stackexchange.com/q/264635/70524 (Жиль всегда дает очень хорошие ответы) – muru 19 November 2016 в 19:30

Кто-то пропустил 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
4
ответ дан 23 May 2018 в 04:04

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

$ echo "foo.foo.foo" | xargs -d .
foo foo foo
1
ответ дан 23 May 2018 в 04:04

Другие вопросы по тегам:

Похожие вопросы: