Comment tr traduit-il un mot en un autre?

9

J'ai un fichier ma.txtet il contient la sortie de ls -l; lorsque j'exécute la trcommande ( tr "nik-pc" "root") j'obtiens cette sortie:

nik-pc@nik:~$ cat ma.txt 
total 52
drwxr-xr-x 2 nik-pc nik-pc 4096 Mar 11 11:33 Desktop
lrwxrwxrwx 1 nik-pc nik-pc    2 Mar  8 22:54 di -> hd
drwxr-xr-x 3 nik-pc nik-pc 4096 Mar 13 13:28 Documents
drwxr-xr-x 7 nik-pc nik-pc 4096 Mar 14 18:21 Downloads
drwxr-xr-x 2 nik-pc nik-pc 4096 Mar 11 09:39 dwhelper
-rw-r--r-- 1 nik-pc nik-pc 2134 Mar 13 17:40 hd
-rw-r--r-- 1 nik-pc nik-pc    3 Mar 13 15:34 m
-rw-r--r-- 1 nik-pc nik-pc    0 Mar 17 19:48 ma.txt
drwxr-xr-x 3 nik-pc nik-pc 4096 Mar 13 14:58 Music
drwxr-xr-x 2 nik-pc nik-pc 4096 Mar  5 12:30 Pictures
drwxr-xr-x 2 nik-pc nik-pc 4096 Mar  5 11:44 Public
drwxr-xr-x 2 nik-pc nik-pc 4096 Mar 13 15:58 sd
drwxr-xr-x 2 nik-pc nik-pc 4096 Mar  5 11:44 Templates
drwxr-xr-x 2 nik-pc nik-pc 4096 Mar  5 11:44 Videos
drwxr-xr-x 2 nik-pc nik-pc 4096 Mar 11 11:33 xdm-helper

nik-pc@nik:~$ tr "nik-pc" "root" < ma.txt 
tttat 52
drwxr-xr-x 2 too-tt too-tt 4096 Mar 11 11:33 Desottt
trwxrwxrwx 1 too-tt too-tt    2 Mar  8 22:54 do -> hd
drwxr-xr-x 3 too-tt too-tt 4096 Mar 13 13:28 Dttutetts
drwxr-xr-x 7 too-tt too-tt 4096 Mar 14 18:21 Dtwtttads
drwxr-xr-x 2 too-tt too-tt 4096 Mar 11 09:39 dwhetter
-rw-r--r-- 1 too-tt too-tt 2134 Mar 13 17:40 hd
-rw-r--r-- 1 too-tt too-tt    3 Mar 13 15:34 t
-rw-r--r-- 1 too-tt too-tt    0 Mar 17 19:48 ta.txt
drwxr-xr-x 3 too-tt too-tt 4096 Mar 13 14:58 Musot
drwxr-xr-x 2 too-tt too-tt 4096 Mar  5 12:30 Pottures
drwxr-xr-x 2 too-tt too-tt 4096 Mar  5 11:44 Pubtot
drwxr-xr-x 2 too-tt too-tt 4096 Mar 13 15:58 sd
drwxr-xr-x 2 too-tt too-tt 4096 Mar  5 11:44 Tetttates
drwxr-xr-x 2 too-tt too-tt 4096 Mar  5 11:44 Vodets
drwxr-xr-x 2 too-tt too-tt 4096 Mar 11 11:33 xdt-hetter

À la première ligne, il a remplacé "nik" par "too" et l'orthographe de "Desktop" est devenue "Desottt".

Pourquoi est-ce? Quelle est la logique derrière cela?

Manish Bharti
la source
3
info coreutils 'tr invocation'vous explique en détail ce qui trfait.
Nephente
4
Qu'essayez-vous de faire au fait? La commande a fait exactement ce que vous lui aviez demandé de faire, mais je suppose que vous voulez réellement la remplacer nik-pcpar root?
kos
3
La première étape consiste toujours à vérifier la page de manuel de la commande.
Mostafa Ahangarha
1
@DavidZ: Notez que nc'est également dans la k-pplage. Le résultat d'un caractère apparaissant plus d'une fois sur le premier jeu n'est pas spécifié par POSIX.
hmakholm a quitté Monica
1
Je pense que ce dont vous avez vraiment besoin, c'est de la sedcommande ... ls -l | sed 's/nik-pc/root/'ferait ce que vous voulez. trest pour convertir des caractères simples - par exemple. minuscule à majuscule, ou décalage de ligne de style dos (\ r) à style Unix (\ n), ou quelque chose comme remplacer toutes les barres obliques inverses (Windows) par des barres obliques. Il peut également supprimer des caractères "indésirables", par exemple. tous les chiffres ou toutes les lettres majuscules.
Baard Kopperud

Réponses:

16

trtraduit une chaîne de caractères. Il recherche les lettres du premier ensemble et les remplace par celles du deuxième ensemble.

Vous aviez nik-pccomme premier set. trétend la k-ppartie en ce sens à toutes les lettres comprises entre "k" et "p", de sorte que l'ensemble est égal à niklmnopc.

Votre deuxième set était root.

Ce trqui fait maintenant est de rechercher toutes les occurrences du premier caractère dans le premier ensemble (évalué) et de les remplacer par le premier caractère du deuxième ensemble. Lorsqu'il n'y a plus de caractère dans le set 2, il répète simplement son dernier caractère. Voir le tableau ci-dessous:

n --> r
i --> o
k --> o
l --> t
m --> t
n --> t
o --> t
p --> t
c --> t

Alors maintenant, il est clair pourquoi par exemple "Desktop" devient "Desottt". Le comportement est entièrement correct et destiné de cette façon.


Ce que vous recherchez à la place peut être obtenu en utilisant sed:

sed 's/nik-pc/root/g' ma.txt

La syntaxe est la suivante:

sed 's/SEARCH_PATTERN/REPLACE_STRING/FLAGS' INPUT_FILE

Nous le laissons donc rechercher le motif "nik-pc" et remplacer la correspondance entière par "root". Nous devons ajouter le drapeau "g" pour permettre le remplacement global. Sans cela, il ne remplacerait que chaque première correspondance par ligne.

Byte Commander
la source
Ce tableau avec des flèches rend l'explication encore plus claire, j'aime ça. + 1-ed. Un utilisateur pourrait probablement créer quelque chose de similaire avecprintf "A\nB\nC\n" | tr 'ABC' '12'
Sergiy Kolodyazhnyy
18

trest pour traduire des caractères, pas pour des mots complets. Il peut traduire des ensembles. Dans votre exemple, vous avez "nik-pc" comme premiers caractères de collection, et "root" en est un autre. En fait, k-pest une plage, donc elle inclut tous les caractères de k à p. Il fera correspondre les caractères un par un, donc n se traduira par r, i en o, k en o, et tout ce qui au-delà du 4ème caractère sera t. C'est pourquoi vous avez "Desktop" traduit en "Desottt"

Vous pouvez le voir plus clairement dans cet exemple:

$ echo "ABCDEF" | tr "ABCDEF"  "12"                            
122222

Ici, vous pouvez voir que le tr jeu 1 a D en position 4. Mais le jeu 2 n'a pas de position 4, il utilisera donc la dernière position que le jeu 2 doit traduire.

Ce que vous faites, c'est traduire un mot en un autre. Ce que vous voulez faire, c'est utiliser un outil plus avancé comme sedou awk.

Par exemple,

$ ls -l /etc/passwd | awk '{gsub(/root/,"TEST");print}'        
-rw-r--r-- 1 TEST TEST 2575 Feb 29 12:30 /etc/passwd
Sergiy Kolodyazhnyy
la source
6
OU sed s / nik-pc / root / g ma.txt> ma2.txt
Bruni
1
Tu étais beaucoup plus rapide que moi @Serg ...: P
Byte Commander
2
@ByteCommander J'ai peut-être gagné en vitesse, mais je pense que votre réponse gagne en qualité
Sergiy Kolodyazhnyy