How does tr translate one word to another?
tr
is for translating characters, not for complete words. It can translate sets. In your example you have "nik-pc" as first collection chars, and "root" is another. In fact, k-p
is a range, so it includes all chars from k to p. It will match chars one by one, so n will translate to r, i to o, k to o, and whatever else beyond 4th char will be t. That's why you have "Desktop" translated to "Desottt"
You can see it more clearly in this example:
$ echo "ABCDEF" | tr "ABCDEF" "12"
122222
Here you can see tr
set 1 have D in position 4. But set 2 has no position 4, so it will use last position set 2 has to translate.
What you are doing is translating one word into another. What you want to do is use more advanced tool like sed
or awk
.
For instance,
$ ls -l /etc/passwd | awk '{gsub(/root/,"TEST");print}'
-rw-r--r-- 1 TEST TEST 2575 Feb 29 12:30 /etc/passwd
tr
translates a string character-wise. It searches the letters from the first set and replaces them by those form the second set.
You had nik-pc
as first set. tr
expands the k-p
part in that to all letters in the range from "k" to "p", so the set is equal to niklmnopc
.
Your second set was root
.
What tr
now does is to search all occurrences of the first character in the (evaluated) first set and replace them with the first character of the second set. When there is no more character in set 2, it simply repeates its last character. See the table below:
n --> r
i --> o
k --> o
l --> t
m --> t
n --> t
o --> t
p --> t
c --> t
So now it's clear why e.g. "Desktop" becomes "Desottt". The behaviour is fully correct and intended this way.
What you're looking for instead can be achieved using sed
:
sed 's/nik-pc/root/g' ma.txt
The syntax is this:
sed 's/SEARCH_PATTERN/REPLACE_STRING/FLAGS' INPUT_FILE
So we let it search for the pattern "nik-pc" and replace the entire match with "root". We need to add the "g" flag to enable global replacing. Without that, it would only replace each first match per line.