How do the '-s', '-t', and '-c' options of the tr command work in Unix?
-s
Switch: Squeeze (remove repeated characters)
echo i am a good boy | tr -s good bad
output:
i am a bd bdy
There are two things happening behind the scenes that make this happen. Firstly, if the second argument to tr
is shorter than the first then the last character in the 2nd arg is repeated to make it the same length as the first. So the equivalent command is:
echo i am a good boy | tr -s good badd
The other thing that is happening is when characters in the first argument are repeated they overwrite any previous occurrence (I'm referring to the two oo
s in good
). This makes the command now equivalent to:
echo i am a good boy | tr -s god bdd
(the second o
to d
replacement overwrites the previous o
to a
replacement, making it redundant)
Without the -s
switch the output would be
i am a bddd bdy
With the -s
switch tr
'squeezes' any repeated characters that are listed in the last argument leaving the final output:
i am a bd bdy
-c
Switch: Complement
The -c
switch is used to match the complement of the first argument (i.e. all characters not listed in arg 1). As a result, arg 1 will contain many letters (256-3). Now, the same thing happens to arg 2 as in the previous case: Arg 2's final character gets repeated to match the length or Arg 1. So the original statement:
echo i am a good boy | tr -c good bad
is equivalent to:
echo i am a good boy | tr abcefhijklmnp... baddddddddddd...
(note the missing g
, o
and d
in the first set, also note that d
will replace every other character in the second set -- including the space character)
This is why i am a good boy
turns into dddddddgoodddodd
More info here: http://www.linuxjournal.com/article/2563
Your understanding of -s
is incorrect, it replaces repeated occurrences of characters in set 1 in the input with a single character. it does not modify the set, eg.
echo i am a good boy | tr -s god bad
gives
i am a bad bay
The -c
option replaces set 1 with its complement (ie. the set of all characters not contained in set 1). You can use this to remove all but the specified characters for example.
echo i am a good boy | tr -cd gobdy
outputs
goodboy