Действительно ли TR команды способен к переводу символов в более длинные строки?

Отметьте то использование O_DIRECT склонно перестать работать в более новых ядрах с более новыми файловыми системами. См. этот отчет об ошибках, например. Так не только использование, часто сомнительное, оно не будет, вероятно, работать вообще в подрастающем поколении дистрибутивов Linux. Таким образом, я не поставил бы производительность своего кода его, даже если Вы, оказывается, можете доказать, что это могло бы обладать преимуществом.

6
03.09.2018, 17:20
4 ответа

Я не знаю, какую оболочку Вы используете, но возможности tr не встроенное. Это уверено не для меня в ударе или zsh :) Попытайтесь работать type tr лично убеждаться.

Во всей вероятности, sed правильный инструмент для задания. Это - то, для чего это было сделано.По обстоятельствам perl и awk также.

Если у Вас есть очень простые случаи и если Вы работаете со строковой переменной вместо конвейера, Вам могло бы сойти с рук реальное встроенное такое как использование поиска строки удара и замены на переменной.

string="Stuf with <tag> in it."
escaped=${string//</&lt;}
escaped=${escaped//>/&gt;}
echo $escaped
4
27.01.2020, 20:25

Замена нескольких строк с другим набором нескольких строк становится грязной, если Вы хотите использовать стандартную обработку параметра. Обычно, команды берут ряд атомарных параметров и затем ряда атомарных аргументов, и последовательность не имеет значения кроме этого, аргументы прибывают после параметров (разделенный -- если неоднозначный). Как Вы создали бы резюме в этом случае?

Вот простая функция, которая должна сделать задание для простых замен:

$ trs() {
    local string=$1
    shift
    for replacement in "$@"
    do
        string="$(sed -e "s/$replacement/g" <<< "$string")"
    done
    printf "$string"
}
$ trs '1 2 3' '1/foo' '2 3/bar baz'
foo bar baz

Кроме того, Вы могли работать с парами параметров:

$ trs() {
    local string=$1
    shift
    while [ $# -gt 0 ]
    do
        string="$(sed -e "s/$1/$2/g" <<< "$string")"
        shift 2
    done
    printf "$string"
}
$ trs '1 2 3' 1 foo '2 3' 'bar baz'
foo bar baz
3
27.01.2020, 20:25
  • 1
    Это хорошие функции. Я надеялся найти тот, который легко доступен во внешней системе. –   08.07.2011, 17:48
  • 2
    Между прочим, они не обработали бы строки, содержащие специальные строки как \? или &. –   08.07.2011, 17:54
  • 3
    @Tim Nordenfur: Если Вы только хотите заменить литералы, необходимо выйти из него, да. Этот подход допускает регулярные выражения, который, конечно, является другой кучей проблем. –  l0b0 08.07.2011, 18:20

sed может быть страшный, но простой символ для строкового представления замены с sed не действительно слишком плохо.

Занимать место x со строкой bar, сделайте:

{something-that-outputs-something-on-stdout} | sed -e 's/x/bar/g'

если это - файл, Вы желаете обработать, можно использовать:

sed -e 's/x/bar/g' {filename}

("g" в средствах конца, "глобальных", что означает, заменяют всеми случаями в строке и не только первой),

2
27.01.2020, 20:25
  • 1
    я не боюсь sed; я охватываю его. Причина, которую я спрашиваю, состоит в том, что использование более простых инструментов, кажется, обычно поощряется, например, нет sedзвените, когда Вы будете мочь cut. –   08.07.2011, 17:44
  • 2
    как насчет нет catлуг, когда можно просто использовать sed –  xenoterracide 08.07.2011, 18:44
  • 3
    @xenoterracide: Положительная сторона, отредактированный ответ. –  LawrenceC 08.07.2011, 19:02
  • 4
    Единственная вещь, которую я не люблю здесь, это становится довольно трудным заменить новую строку \n со строкой как ';' использование sed: sed: Как я могу заменить новую строку (\n)? - Переполнение стека отмечает ту плоскость s/// не работает, и необходимо войти в "синтаксис" пространства шаблона... –  sdaau 24.01.2015, 05:12

Если вы знаете, какой будет более длинная строка, sed -e s/xx/yy/gответы будут надежными.

Однако, если вы хотите быть более общим и принимать любую строку в качестве входных данных, например. из аргументов функции вы не можете использовать sed :, вам придется экранировать строку, прежде чем использовать ее в регулярном выражении, что очень сложно.

Чтобы сделать это более надежно, вы можете использовать этот лайнер:

python -c '(lambda s: s.stdout.write(s.stdin.read().replace(*s.argv[1:])))(__import__("sys"))'

Добавьте его как псевдоним в.bashrc для удобства использования:

alias trs='python -c '\''(lambda s: s.stdout.write(s.stdin.read().replace(*s.argv[1:])))(__import__("sys"))'\'''

и:

$ echo /some-path/file | trs -path /dir1/dir2
/some/dir1/dir2/file

фон :Я использую это для другого псевдонима; cds, чтобы имитировать поведение zsh "cd foo bar", которое заменяет fooна barв вашем pwd:

$ function cds { cd "$(pwd | trs "$1" "$2")" ; }

$ mkdir -p /tmp/foo /tmp/bar
$ cd /tmp/foo
$ cds foo bar
$ pwd
/tmp/bar

Это не сработало бы с версией sed, если бы я когда-нибудь передал /или другой не -regex -безопасный символ.

0
27.01.2020, 20:25

Теги

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