In che modo tr traduce una parola in un'altra?


9

Ho un file ma.txte contiene l'output di ls -l; quando eseguo il trcomando ( tr "nik-pc" "root") ottengo questo output:

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

Alla prima riga ha sostituito "nik" con "too" e l'ortografia di "Desktop" è diventata "Desottt".

Perchè è questo? Qual è la logica dietro di esso?


3
info coreutils 'tr invocation'ti dice in dettaglio cosa trfa.
Nephente,

4
Cosa stai cercando di fare a proposito? Il comando ha fatto esattamente quello che ha detto di fare, ma credo che in realtà si desidera sostituire nik-pccon root?
kos

3
Il primo passo è sempre quello di controllare la pagina man del comando.
Mostafa Ahangarha,

1
@DavidZ: si noti che nè anche k-pnell'intervallo. Il risultato di un personaggio che appare più di una volta nel primo set non è specificato da POSIX.
Hmakholm è rimasta su Monica il

1
Penso che ciò di cui hai veramente bisogno, sia il sedcomando ... ls -l | sed 's/nik-pc/root/'farebbe quello che vuoi. trserve per convertire singoli caratteri, ad es. minuscole a maiuscole o line-shift in stile dos (\ r) in stile Unix (\ n) o qualcosa di simile alla sostituzione di tutte le barre rovesciate (Windows) con barre. Può anche eliminare caratteri "indesiderati", ad es. tutti i numeri o tutte le lettere maiuscole.
Baard Kopperud,

Risposte:


16

trtraduce una stringa in termini di carattere. Cerca le lettere del primo set e le sostituisce con quelle del secondo set.

Hai avuto nik-pccome primo set. trespande la k-pparte in quella a tutte le lettere nell'intervallo da "k" a "p", quindi l'insieme è uguale a niklmnopc.

Il tuo secondo set è stato root.

Ciò che trora fa è cercare tutte le occorrenze del primo carattere nel primo set (valutato) e sostituirle con il primo carattere del secondo set. Quando non ci sono più personaggi nel set 2, ripete semplicemente il suo ultimo personaggio. Vedi la tabella qui sotto:

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

Quindi ora è chiaro perché ad esempio "Desktop" diventa "Desottt". Il comportamento è completamente corretto e inteso in questo modo.


Quello che stai cercando invece può essere realizzato usando sed:

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

La sintassi è questa:

sed 's/SEARCH_PATTERN/REPLACE_STRING/FLAGS' INPUT_FILE

Quindi gli permettiamo di cercare il modello "nik-pc" e di sostituire l'intera corrispondenza con "root". Dobbiamo aggiungere il flag "g" per consentire la sostituzione globale. Senza quello, sostituirebbe solo ogni prima corrispondenza per riga.


Quella tabella con le frecce rende la spiegazione ancora più chiara, mi piace. + 1 ed. Un utente potrebbe probabilmente fare qualcosa di simile conprintf "A\nB\nC\n" | tr 'ABC' '12'
Sergiy Kolodyazhnyy

18

trserve per tradurre caratteri, non per parole complete. Può tradurre set. Nel tuo esempio hai "nik-pc" come primo carattere di raccolta e "root" è un altro. In effetti, k-pè un intervallo, quindi include tutti i caratteri da k a p. Abbinerà i caratteri uno per uno, quindi n si tradurrà in r, i in o, k in oe qualsiasi altra cosa oltre il 4 ° carattere sarà t. Ecco perché hai "Desktop" tradotto in "Desottt"

Puoi vederlo più chiaramente in questo esempio:

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

Qui puoi vedere il tr set 1 con D in posizione 4. Ma il set 2 non ha posizione 4, quindi utilizzerà l'ultima posizione che il set 2 deve tradurre.

Quello che stai facendo è tradurre una parola in un'altra. Quello che vuoi fare è usare strumenti più avanzati come sedo awk.

Per esempio,

$ ls -l /etc/passwd | awk '{gsub(/root/,"TEST");print}'        
-rw-r--r-- 1 TEST TEST 2575 Feb 29 12:30 /etc/passwd

6
O sed s / nik-pc / root / g ma.txt> ma2.txt
Bruni

1
Sei stato molto più veloce di me @Serg ...: P
Comandante di byte

2
@ByteCommander Potrei aver vinto in velocità, ma penso che la tua risposta vince in termini di qualità
Sergiy Kolodyazhnyy
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.