Làm thế nào để tr dịch một từ này sang một từ khác?


9

Tôi có một tập tin ma.txtvà nó chứa đầu ra của ls -l; Khi tôi chạy trlệnh ( tr "nik-pc" "root") tôi nhận được kết quả này:

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

Ở dòng một, nó thay thế "nik" bằng "too" và cách đánh vần là "Desktop" trở thành "Desottt".

Tại sao lại thế này? Logic đằng sau nó là gì?


3
info coreutils 'tr invocation'cho bạn biết chi tiết những gì trkhông.
Nepeavere 17/03/2016

4
Nhân tiện, bạn đang cố gắng làm gì? Lệnh đã làm chính xác những gì bạn bảo nó làm, nhưng tôi đoán bạn thực sự muốn thay thế nik-pcbằng root?
kos

3
Bước đầu tiên là luôn luôn kiểm tra trang man của lệnh.
Mostafa Ahangarha 17/03/2016

1
@DavidZ: Lưu ý rằng ncũng nằm trong k-pphạm vi. Kết quả của một nhân vật xuất hiện nhiều hơn một lần trên tập đầu tiên là không xác định bởi POSIX.
hmakholm còn lại của Monica

1
Tôi nghĩ rằng những gì bạn thực sự cần, là sedlệnh ... ls -l | sed 's/nik-pc/root/'sẽ làm những gì bạn muốn. trlà để chuyển đổi các ký tự đơn - ví dụ. viết thường từ viết thường sang viết thường hoặc chuyển đổi kiểu chữ dos (\ r) sang kiểu Unix (\ n) hoặc một cái gì đó như thay thế tất cả dấu gạch chéo ngược (Windows) bằng dấu gạch chéo. Nó cũng có thể xóa các ký tự "không mong muốn", vd. tất cả các số hoặc tất cả các chữ cái viết hoa.
Baard Kopperud 17/03/2016

Câu trả lời:


16

trdịch một chuỗi ký tự-khôn ngoan. Nó tìm kiếm các chữ cái từ bộ thứ nhất và thay thế chúng bằng các mẫu thứ hai.

Bạn đã có nik-pcnhư tập đầu tiên. trmở rộng k-pphần trong đó cho tất cả các chữ cái trong phạm vi từ "k" đến "p", vì vậy tập hợp bằng niklmnopc.

Bộ thứ hai của bạn là root.

Những gì trbây giờ là tìm kiếm tất cả các lần xuất hiện của ký tự đầu tiên trong tập đầu tiên (được đánh giá) và thay thế chúng bằng ký tự đầu tiên của tập thứ hai. Khi không còn nhân vật nào trong tập 2, nó chỉ đơn giản lặp lại ký tự cuối cùng của nó. Xem bảng dưới đây:

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

Vì vậy, bây giờ rõ ràng tại sao ví dụ "Máy tính để bàn" trở thành "Desottt". Các hành vi là hoàn toàn chính xác và dự định theo cách này.


Thay vào đó, những gì bạn đang tìm kiếm có thể đạt được bằng cách sử dụng sed:

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

Cú pháp là thế này:

sed 's/SEARCH_PATTERN/REPLACE_STRING/FLAGS' INPUT_FILE

Vì vậy, chúng tôi cho phép nó tìm kiếm mẫu "nik-pc" và thay thế toàn bộ khớp bằng "root". Chúng ta cần thêm cờ "g" để cho phép thay thế toàn cầu. Không có điều đó, nó sẽ chỉ thay thế mỗi trận đấu đầu tiên trên mỗi dòng.


Bảng đó với mũi tên làm cho lời giải thích thậm chí rõ ràng hơn, tôi thích điều đó. + 1-ed. Một người dùng có thể có thể làm một cái gì đó tương tự vớiprintf "A\nB\nC\n" | tr 'ABC' '12'
Sergiy Kolodyazhnyy 17/03/2016

18

trlà để dịch các ký tự, không phải cho các từ hoàn chỉnh. Nó có thể dịch bộ. Trong ví dụ của bạn, bạn có "nik-pc" là ký tự bộ sưu tập đầu tiên và "root" là một cái khác. Trong thực tế, k-plà một phạm vi, vì vậy nó bao gồm tất cả các ký tự từ k đến p. Nó sẽ ghép từng ký tự một, vì vậy n sẽ dịch sang r, i thành o, k thành o và bất cứ thứ gì khác ngoài char thứ 4 sẽ là t. Đó là lý do tại sao bạn có "Desktop" được dịch thành "Desottt"

Bạn có thể thấy nó rõ hơn trong ví dụ này:

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

Ở đây bạn có thể thấy tr tập 1 có D ở vị trí 4. Nhưng tập 2 không có vị trí 4, nên nó sẽ sử dụng vị trí cuối cùng tập 2 phải dịch.

Những gì bạn đang làm là dịch một từ này sang một từ khác. Những gì bạn muốn làm là sử dụng công cụ nâng cao hơn như sedhoặc awk.

Ví dụ,

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

6
HOẶC sed s / nik-pc / root / g ma.txt> ma2.txt
Bruni

1
Bạn nhanh hơn tôi rất nhiều @Serg ...: P
Chỉ huy Byte

2
@ByteCommander Tôi có thể đã chiến thắng về tốc độ, nhưng tôi nghĩ câu trả lời của bạn chiến thắng về chất lượng
Sergiy Kolodyazhnyy 17/03/2016
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.