Bagaimana tr menerjemahkan satu kata ke kata lain?

9

Saya punya file ma.txtdan berisi output dari ls -l; ketika saya menjalankan trperintah ( tr "nik-pc" "root") saya mendapatkan output ini:

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

Pada baris pertama ia menggantikan "nik" dengan "terlalu" dan ejaan "Desktop" menjadi "Desottt".

Kenapa ini? Apa logika di baliknya?

Manish Bharti
sumber
3
info coreutils 'tr invocation'memberitahumu secara rinci apa yang trdilakukannya.
Nephente
4
Apa yang Anda coba lakukan? Perintah itu persis apa yang Anda diberitahu untuk melakukan, tapi saya kira Anda benar-benar ingin mengganti nik-pcdengan root?
kos
3
Langkah pertama adalah selalu memeriksa halaman manual dari perintah.
Mostafa Ahangarha
1
@ DavidZ: Catatan yang njuga di k-pkisaran. Hasil karakter yang muncul lebih dari sekali pada set pertama tidak ditentukan oleh POSIX.
hmakholm tersisa Monica
1
Saya pikir apa yang sebenarnya Anda butuhkan, adalah sedperintah ... ls -l | sed 's/nik-pc/root/'akan melakukan apa yang Anda inginkan. tradalah untuk mengkonversi karakter tunggal - mis. huruf kecil ke huruf besar, atau dos-style lineshift (\ r) ke Unix-style (\ n), atau sesuatu seperti mengganti semua garis miring terbalik (Windows) dengan garis miring. Itu juga dapat menghapus karakter "yang tidak diinginkan", misalnya. semua angka atau semua huruf besar.
Baard Kopperud

Jawaban:

16

trmenerjemahkan karakter string-bijaksana. Ini mencari huruf-huruf dari set pertama dan menggantinya dengan yang membentuk set kedua.

Anda memiliki nik-pcset pertama. trperluas k-pbagian itu ke semua huruf dalam kisaran dari "k" hingga "p", sehingga himpunannya sama dengan niklmnopc.

Set kedua Anda adalah root.

Apa yang trsekarang dilakukan adalah mencari semua kemunculan karakter pertama di set pertama (yang dievaluasi) dan menggantinya dengan karakter pertama set kedua. Ketika tidak ada lagi karakter di set 2, itu hanya mengulangi karakter terakhirnya. Lihat tabel di bawah ini:

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

Jadi sekarang sudah jelas mengapa misalnya "Desktop" menjadi "Desottt". Perilaku ini sepenuhnya benar dan dimaksudkan dengan cara ini.


Apa yang Anda cari malah bisa dicapai dengan menggunakan sed:

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

Sintaksnya adalah ini:

sed 's/SEARCH_PATTERN/REPLACE_STRING/FLAGS' INPUT_FILE

Jadi kami membiarkannya mencari pola "nik-pc" dan mengganti seluruh kecocokan dengan "root". Kita perlu menambahkan bendera "g" untuk memungkinkan penggantian global. Tanpa itu, itu hanya akan mengganti setiap pertandingan pertama per baris.

Komandan Byte
sumber
Meja dengan panah itu membuat penjelasannya lebih jelas, saya suka itu. + 1-red. Seorang pengguna mungkin bisa membuat sesuatu yang mirip denganprintf "A\nB\nC\n" | tr 'ABC' '12'
Sergiy Kolodyazhnyy
18

tradalah untuk menerjemahkan karakter, bukan untuk kata-kata lengkap. Itu bisa menerjemahkan set. Dalam contoh Anda, Anda memiliki "nik-pc" sebagai chars koleksi pertama, dan "root" adalah yang lain. Bahkan, k-padalah rentang, jadi itu mencakup semua karakter dari k ke p. Ini akan mencocokkan karakter satu per satu, jadi n akan menerjemahkan ke r, i ke o, k ke o, dan apa pun yang melebihi karakter ke 4 akan t. Itu sebabnya Anda menerjemahkan "Desktop" ke "Desottt"

Anda dapat melihatnya dengan lebih jelas dalam contoh ini:

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

Di sini Anda dapat melihat tr set 1 memiliki D di posisi 4. Tetapi set 2 tidak memiliki posisi 4, sehingga akan menggunakan posisi terakhir yang ditetapkan 2 harus diterjemahkan.

Apa yang Anda lakukan adalah menerjemahkan satu kata ke kata lain. Apa yang ingin Anda lakukan adalah menggunakan alat yang lebih canggih seperti sedatau awk.

Contohnya,

$ ls -l /etc/passwd | awk '{gsub(/root/,"TEST");print}'        
-rw-r--r-- 1 TEST TEST 2575 Feb 29 12:30 /etc/passwd
Sergiy Kolodyazhnyy
sumber
6
ATAU sed s / nik-pc / root / g ma.txt> ma2.txt
Bruni
1
Anda jauh lebih cepat daripada saya @Serg ...: P
Byte Commander
2
@ByteCommander Saya mungkin telah menang dalam kecepatan, tapi saya pikir jawaban Anda menang dalam kualitas
Sergiy Kolodyazhnyy