Wie übersetzt tr ein Wort in ein anderes?

9

Ich habe eine Datei ma.txtund sie enthält die Ausgabe von ls -l; Wenn ich den trBefehl ( tr "nik-pc" "root") ausführe, erhalte ich folgende Ausgabe:

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

In Zeile eins wurde "nik" durch "too" ersetzt und die Schreibweise von "Desktop" wurde zu "Desottt".

Warum ist das? Was ist Logik dahinter?

Manish Bharti
quelle
3
info coreutils 'tr invocation'sagt Ihnen im Detail, was trtut.
Nephente
4
Was versuchst du übrigens zu tun? Der Befehl ist genau das, was Sie ihm gesagt , zu tun, aber ich denke , man tatsächlich ersetzen mag nik-pcmit root?
Kos
3
Der erste Schritt besteht immer darin, die Manpage des Befehls zu überprüfen.
Mostafa Ahangarha
1
@ DavidZ: Beachten Sie, dass dies nebenfalls im k-pBereich liegt. Das Ergebnis eines Zeichens, das im ersten Satz mehrmals vorkommt, wird von POSIX nicht angegeben.
Hmakholm verließ Monica
1
Ich denke, was Sie wirklich brauchen, ist der sedBefehl ... ls -l | sed 's/nik-pc/root/'würde tun, was Sie wollen. trdient zum Konvertieren einzelner Zeichen - z. Kleinbuchstaben in Großbuchstaben oder Zeilenumbruch im Dos-Stil (\ r) in Unix-Stil (\ n) oder so etwas wie das Ersetzen aller Backslashes (Windows) durch Schrägstriche. Es können auch "unerwünschte" Zeichen gelöscht werden, z. alle Zahlen oder alle Großbuchstaben.
Baard Kopperud

Antworten:

16

trübersetzt eine Zeichenfolge zeichenweise. Es durchsucht die Buchstaben aus dem ersten Satz und ersetzt sie durch die Buchstaben aus dem zweiten Satz.

Du hattest nik-pcals erstes gesetzt. trerweitert den k-pTeil darin auf alle Buchstaben im Bereich von "k" bis "p", so dass die Menge gleich ist niklmnopc.

Dein zweiter Satz war root.

Was trjetzt tut , ist alle Vorkommen des ersten Zeichens in dem (ausgewertet) ersten Satz zu suchen und sie mit dem ersten Zeichen des zweiten Satzes ersetzen. Wenn in Satz 2 kein Zeichen mehr vorhanden ist, wird einfach das letzte Zeichen wiederholt. Siehe folgende Tabelle:

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

Jetzt ist klar, warum aus "Desktop" "Desottt" wird. Das Verhalten ist völlig korrekt und auf diese Weise beabsichtigt.


Was Sie stattdessen suchen, können Sie erreichen mit sed:

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

Die Syntax lautet wie folgt:

sed 's/SEARCH_PATTERN/REPLACE_STRING/FLAGS' INPUT_FILE

Also lassen wir es nach dem Muster "nik-pc" suchen und ersetzen die gesamte Übereinstimmung durch "root". Wir müssen das "g" -Flag hinzufügen, um das globale Ersetzen zu ermöglichen. Ohne das würde es nur jede erste Übereinstimmung pro Zeile ersetzen.

Byte Commander
quelle
Diese Tabelle mit den Pfeilen macht die Erklärung noch deutlicher, das gefällt mir. + 1-ed. Ein Benutzer könnte wahrscheinlich etwas Ähnliches mitprintf "A\nB\nC\n" | tr 'ABC' '12'
Sergiy Kolodyazhnyy
18

trdient zum Übersetzen von Zeichen, nicht für vollständige Wörter. Es kann Mengen übersetzen. In Ihrem Beispiel haben Sie "nik-pc" als Zeichen für die erste Sammlung, und "root" ist ein anderes. In der Tat k-pist ein Bereich, so dass er alle Zeichen von k bis p enthält. Es werden die Zeichen nacheinander abgeglichen, sodass n in r, i in o, k in o übersetzt wird und was auch immer jenseits des 4. Zeichens t ist. Deshalb haben Sie "Desktop" in "Desottt" übersetzt.

Sie können es in diesem Beispiel deutlicher sehen:

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

Hier sehen Sie, dass tr Satz 1 D in Position 4 hat. Satz 2 hat jedoch keine Position 4, sodass die letzte Position verwendet wird, die Satz 2 übersetzen muss.

Was Sie tun, ist ein Wort in ein anderes zu übersetzen. Was Sie tun möchten, ist ein fortgeschritteneres Tool wie sedoder awk.

Zum Beispiel,

$ ls -l /etc/passwd | awk '{gsub(/root/,"TEST");print}'        
-rw-r--r-- 1 TEST TEST 2575 Feb 29 12:30 /etc/passwd
Sergiy Kolodyazhnyy
quelle
6
ODER sed s / nik-pc / root / g ma.txt> ma2.txt
Bruni
1
Sie waren viel schneller als ich @Serg ...: P
Byte Commander
2
@ ByteCommander Ich habe vielleicht in der Geschwindigkeit gewonnen, aber ich denke, Ihre Antwort gewinnt in der Qualität
Sergiy Kolodyazhnyy