Comment fonctionnent les options '-s', '-t' et '-c' de la commande tr sous Unix?

12

Je suis confus quant à la façon -s, -tet -coptions de travail dans la tr commande. Quand je fais

echo I am a good boy | tr good bad

J'obtiens la sortie:

I am a bddd bdy

Ceci est tout à fait compréhensible, car oest répété dans good. Le dernier changement possible à la place de oest d, et donc de la sortie.

Maintenant, quand je fais

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

la sortie est

I am a bd bdy

L' -soption est censée compresser chaque occurrence répétée de chaque caractère de l'ensemble 1 en une seule occurrence, puis changer chaque caractère de l'ensemble 1 en le caractère correspondant de l'ensemble 2 qui se trouve à la même position.

Il aurait donc dû être

I am a bad bay.

Pourquoi le changement?

De plus, quand je fais

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

Je reçois dddddddgoodddodd

Comment fonctionne l' -coption tr, en se référant à cet exemple?

Et enfin: comment me transformer d'un bon garçon en un mauvais garçon .... :): P Autrement dit,

echo I am a good boy | tr <something>me donne la sortie comme: I am a bad boy.

dig_123
la source

Réponses:

12

-s Switch: Squeeze (supprimez les caractères répétés)

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

production: i am a bd bdy

Il y a deux choses qui se passent dans les coulisses qui rendent cela possible. Premièrement, si le deuxième argument de trest plus court que le premier, le dernier caractère du deuxième argument est répété pour lui donner la même longueur que le premier. La commande équivalente est donc:

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

L'autre chose qui se produit est que lorsque les caractères du premier argument sont répétés, ils écrasent toute occurrence précédente (je fais référence aux deux oos dans good). Cela rend la commande désormais équivalente à:

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

(le deuxième oau dremplacement du précédent remplace oà aremplacer, ce qui rend redondant)

Sans le -scommutateur, la sortie serait

i am a bddd bdy

Avec le -scommutateur tr«serre» tous les caractères répétés qui sont répertoriés dans le dernier argument laissant la sortie finale:

i am a bd bdy

-c Commutateur: complément

Le -ccommutateur est utilisé pour faire correspondre le complément du premier argument (c'est-à-dire tous les caractères non répertoriés dans arg 1). Par conséquent, arg 1 contiendra de nombreuses lettres (256-3). Maintenant, la même chose arrive à arg 2 comme dans le cas précédent: le caractère final d'Arg 2 est répété pour correspondre à la longueur ou Arg 1. Donc, la déclaration d'origine:

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

est équivalent à:

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

(notez les disparus g, oet ddans le premier jeu, notez que dremplacera tous les autres caractères dans le deuxième set - y compris le caractère d'espace)

Voilà pourquoi i am a good boyse transforme endddddddgoodddodd

Plus d'informations ici: http://www.linuxjournal.com/article/2563

ltn100
la source
Généralement correct, sauf que le -scommutateur provoque la trcompression de tous les caractères du dernier argument vers tr(pas le premier, comme vous le dites) qui sont répétés dans l'entrée. Ceci est noté dans l'article que vous avez lié et est expliqué dans le dernier paragraphe de la section "Description" de la page de manuel .
ravron le
4

Votre compréhension de -sest incorrecte, elle remplace les occurrences répétées de caractères de l'ensemble 1 dans l'entrée par un seul caractère. il ne modifie pas l'ensemble, par exemple.

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

donne

i am a bad bay

L' -coption remplace l'ensemble 1 par son complément (c'est-à-dire l'ensemble de tous les caractères non contenus dans l'ensemble 1). Vous pouvez l'utiliser pour supprimer tous les caractères sauf les caractères spécifiés par exemple.

echo i am a good boy | tr -cd gobdy

les sorties

goodboy
Hasturkun
la source
: J'ai obtenu votre point concernant l'option -s, mais ma question est, comment: echo je suis un bon garçon | tr -s good bad donne la sortie comme: je suis un bd bdy cela n'est possible que lorsque cela se produit: d'abord je suis un bon garçon est changé en je suis un bddd bdy puis l'option -s change les occurrences de multiples d's en single c'est à dire: je suis un bddd bdy puis passe à je suis un bddd bdy est-ce ce qui se passe réellement? s'il vous plaît décomposer cela pour moi, même avec l'option -c comment est l'écho je suis un bon garçon | tr -c gobdy donnant ceci: goodboy
1

Les autres réponses couvertes tr« s -s, -tet les -coptions , mais pour être complet:

Vous rencontrez des problèmes parce que vous avez pris le mauvais outil.

  • tr est pour les transformations de caractères
  • sed est pour l'édition de flux.

Étant donné que les deux goodet badsont une séquence de caractères dans le flux sedest une meilleure correspondance.

echo I am a good boy | <something> me donne la sortie comme: I am a bad boy

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

Le s/..../..../est remplaçant. Tout ce qui correspond à la première expression régulière sera remplacé par la seconde. Le /gdrapeau à la fin est pour le remplacement global de cette façon, toutes les occurrences seront remplacées, pas seulement la première.

$ 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.
Aaron Goldman
la source
0

Oui. exactement!

tr -s remplace les instances de caractères répétés par un seul caractère.

(via la page de manuel.)

alors ça va comme ça:

il se convertit gooden bddd. les instances répétées sont 3 'd's.

il remplace donc ces trois instances par une seule instance.

c'est qu'il fait bd. :)

Rahul Mishra
la source
2
Nous ne nous attendons pas à ce que chaque réponse soit parfaite, mais les réponses avec une orthographe, une ponctuation et une grammaire correctes sont plus faciles à lire.
Ashildr