Як я можу змусити 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
Ніколи не пишіть це в "С", якщо ви можете це зробити в "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є більш складним, ніж просто збереження його до змінної та відновлення значення. Відключення IFSта порожній IFSмають різну поведінку, тому вам потрібно перевірити, чи він не встановлений чи просто порожній, на випадок, якщо він був порожнім раніше.
муру

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

3
Тож якби ОП раніше IFSз якихось причин було знято , ця функція встановила б його порожнім, що має іншу поведінку.
муру

2
@fedorqui, на жаль, навіть це не буде працювати; оскільки значення IFS встановлено занадто пізно для аналізу поточного оператора. Насправді вам доведеться використовувати передплату (IFS=.; echo ...). Оскільки ця відповідь використовувала функцію, Серг міг просто змінити дужки на круглі дужки і зовсім не турбуватися про скидання IFS
muru

2
@fedorqui, моє подібне запитання щодо U&L може бути цікавим: unix.stackexchange.com/q/264635/70524 (Gilles завжди дає дуже хороші відповіді)
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.