Как работают параметры '-s', '-t' и '-c' команды tr в Unix?

12

Я запутался в отношении способа -s, -tи -cопции работают в команде tr . Когда я делаю

echo I am a good boy | tr good bad

Я получаю вывод:

I am a bddd bdy

Это вполне понятно, так oкак повторяется в good. Последнее возможно изменение места oIS d, и , следовательно , выход.

Теперь, когда я делаю

echo I am a good boy | tr -s good bad

выход

I am a bd bdy

Предполагается, что -sопция сжимает каждый повторяющийся вхождений каждого символа в наборе 1 в один и затем заменяет каждый символ в наборе 1 на соответствующий символ в наборе 2, который находится в той же позиции.

Так и должно было быть

I am a bad bay.

Почему изменения?

Более того, когда я делаю

echo I am a good boy | tr -c good bad

я получил dddddddgoodddodd

Как работает -cопция tr, ссылаясь на этот пример?

И напоследок: как превратить себя из хорошего мальчика в плохого мальчика .... :): P То есть

echo I am a good boy | tr <something>дает мне вывод как I am a bad boy.

dig_123
источник

Ответы:

12

-s Переключатель: Squeeze (удалить повторяющиеся символы)

echo i am a good boy | tr -s good bad

вывод: i am a bd bdy

За кулисами происходят две вещи, которые делают это возможным. Во-первых, если второй аргумент to trкороче первого, то последний символ во втором аргументе повторяется, чтобы сделать его такой же длины, как и первый. Итак, эквивалентная команда:

echo i am a good boy | tr -s good badd

Другая вещь, которая происходит, - когда символы в первом аргументе повторяются, они перезаписывают любое предыдущее вхождение (я имею в виду два ooв good). Это делает команду теперь эквивалентной:

echo i am a good boy | tr -s god bdd

(второй oдля dзамены перезаписывает предыдущий oна aзамену, что делает его избыточным)

Без -sпереключателя выход будет

i am a bddd bdy

С -sпереключателем tr«сжимает» любые повторяющиеся символы, которые перечислены в последнем аргументе, оставляя окончательный вывод:

i am a bd bdy

-c Переключатель: Дополнение

-cПереключатель используется в соответствии с дополнением первого аргумента (т.е. всех символов , не указанными в агде 1). В результате аргумент 1 будет содержать много букв (256-3). Теперь с аргументом 2 происходит то же самое, что и в предыдущем случае: последний символ аргумента 2 повторяется в соответствии с длиной или аргументом 1. Итак, исходное утверждение:

echo i am a good boy | tr -c good bad

эквивалентно:

echo i am a good boy | tr abcefhijklmnp... baddddddddddd...

(обратите внимание на отсутствие g, oи dв первом сете, также отмечает , что dзаменит все другие символы во втором сете - включая символ пробела)

Вот почему i am a good boyпревращается вdddddddgoodddodd

Более подробная информация здесь: http://www.linuxjournal.com/article/2563

ltn100
источник
В целом правильно, за исключением того, что -sпереключатель заставляет trсжать любые символы из последнего аргумента tr(а не первого, как вы говорите), которые повторяются во входных данных. Это отмечено в статье, на которую вы ссылаетесь, и объясняется в последнем абзаце в разделе «Описание» справочной страницы .
Раврон
4

Ваше понимание -sневерно, оно заменяет повторяющиеся вхождения символов в наборе 1 на входе одним символом. это не изменяет набор, например.

echo i am a good boy | tr -s god bad

дает

i am a bad bay

В -cопции заменяет набор 1 с дополнением (то есть. Множество всех символов не содержится в наборе 1). Вы можете использовать это, чтобы удалить все, кроме указанных символов, например.

echo i am a good boy | tr -cd gobdy

выходы

goodboy
Hasturkun
источник
: Я получил ваше мнение относительно опции -s, но мой вопрос: как, эхо, я хороший мальчик | tr -s good bad дает вывод в виде: я bd bdy, это возможно только тогда, когда это происходит: сначала я хороший мальчик, меняю на bddd bdy, а затем параметр -s изменяет вхождения нескольких d в одинарные то есть: я bddd bdy, затем меняется на bd bdy, это то, что на самом деле происходит? пожалуйста, разбери это для меня, то же самое с опцией -c как эхо я хороший мальчик | tr-cd gobdy дает это: goodboy
1

Другие ответы покрыты tr«ы -s, -tи -cварианты , но для полноты картины :

У вас проблемы, потому что вы выбрали не тот инструмент.

  • tr для преобразования персонажей
  • sed для редактирования потока

Поскольку оба goodи badявляются последовательностью символов в потоке sed, это лучшее совпадение.

echo I am a good boy | <something> дает мне вывод как: I am a bad boy

$ echo I am a good boy | sed s/good/bad/g
I am a bad boy

Это s/..../..../заменитель. Что бы ни соответствовало первому регулярному выражению, оно будет заменено вторым. /gФлаг в конце для глобальной замены таким образом все вхождения будут заменены не только первый.

$ echo I am a good boy and a good boy is me. | sed s/good/bad/
I am a bad boy and a good boy is me.

$ echo I am a good boy and a good boy is me. | sed s/good/bad/g
I am a bad boy and a bad boy is me.
Аарон Голдман
источник
0

да. в точку!

tr -s заменяет экземпляры повторяющихся символов одним символом.

(через страницу руководства.)

Итак, это выглядит так:

это превращается goodв bddd. повторные случаи - 3 'd.

поэтому он заменяет эти три экземпляра одним экземпляром.

то есть это делает его бд. :)

Рахул Мишра
источник
2
Мы не ожидаем, что каждый ответ будет идеальным, но ответы с правильным написанием, пунктуацией и грамматикой легче читать.
Ashildr