tr แปลคำหนึ่งไปอีกคำหนึ่งได้อย่างไร


9

ฉันมีไฟล์ma.txtและมันมีผลลัพธ์ของls -l; เมื่อฉันเรียกใช้trคำสั่ง ( tr "nik-pc" "root") ฉันได้รับผลลัพธ์นี้:

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

ที่บรรทัดแรกมันถูกแทนที่ด้วย "นิก" กับ "เกินไป" และการสะกดคำของ "เดสก์ท็อป" กลายเป็น "Desottt"

ทำไมนี้ ตรรกะอะไรที่อยู่เบื้องหลัง


3
info coreutils 'tr invocation'บอกรายละเอียดสิ่งที่คุณtrทำ
Nephente

4
คุณกำลังพยายามทำอะไรอยู่? คำสั่งทำในสิ่งที่คุณบอกให้ทำ แต่ฉันคิดว่าคุณต้องการแทนที่nik-pcด้วยจริงrootหรือ
kos

3
ขั้นตอนแรกอยู่เสมอเพื่อตรวจสอบหน้าคนของคำสั่ง
Mostafa Ahangarha

1
@DavidZ: โปรดทราบว่าnยังอยู่ในk-pช่วง ผลลัพธ์ของอักขระที่ปรากฏมากกว่าหนึ่งครั้งในชุดแรกนั้นไม่ได้ระบุโดย POSIX
hmakholm ออกเดินทางจากโมนิก้า

1
ฉันคิดว่าสิ่งที่คุณต้องการจริงๆคือsedคำสั่ง ... ls -l | sed 's/nik-pc/root/'จะทำสิ่งที่คุณต้องการ trสำหรับการแปลงอักขระเดี่ยว - เช่น ตัวพิมพ์เล็กเป็นตัวพิมพ์ใหญ่หรือตัวอักษรแบบเส้นเลื่อน (\ r) เป็นแบบ Unix (\ n) หรือสิ่งอื่นเช่นการเปลี่ยนแบ็กสแลชทั้งหมด (Windows) ด้วยเครื่องหมายทับ นอกจากนี้ยังสามารถลบอักขระ "ไม่พึงประสงค์" เช่น ตัวเลขทั้งหมดหรือตัวอักษรตัวพิมพ์ใหญ่ทั้งหมด
Baard Kopperud

คำตอบ:


16

trแปลสตริงอักขระที่ชาญฉลาด มันค้นหาตัวอักษรจากชุดแรกและแทนที่ด้วยชุดรูปแบบที่สอง

คุณมีnik-pcชุดแรก trขยายk-pส่วนหนึ่งในการที่ตัวอักษรทั้งหมดในช่วงจาก "k" เป็น "p" niklmnopcเพื่อให้ชุดมีค่าเท่ากับ

rootชุดที่สองของคุณ

สิ่งที่trจะทำในขณะนี้คือการค้นหาอักขระทั้งหมดในชุดแรก (ประเมิน) ก่อนและแทนที่ด้วยอักขระแรกของชุดที่สอง เมื่อไม่มีตัวละครในชุดที่ 2 มันก็จะทำซ้ำตัวละครสุดท้ายของมัน ดูตารางด้านล่าง:

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

ดังนั้นตอนนี้มันชัดเจนว่าทำไมเช่น "Desktop" กลายเป็น "Desottt" พฤติกรรมนี้ถูกต้องและตั้งใจในลักษณะนี้


สิ่งที่คุณกำลังมองหาสามารถทำได้โดยใช้sed:

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

ไวยากรณ์คือสิ่งนี้:

sed 's/SEARCH_PATTERN/REPLACE_STRING/FLAGS' INPUT_FILE

ดังนั้นเราจึงให้มันค้นหารูปแบบ "nik-pc" และแทนที่การแข่งขันทั้งหมดด้วย "root" เราจำเป็นต้องเพิ่มการตั้งค่าสถานะ "g" เพื่อเปิดใช้งานการแทนที่ทั่วโลก หากไม่มีสิ่งนั้นมันจะแทนที่เฉพาะการแข่งขันครั้งแรกต่อบรรทัด


ตารางที่มีลูกศรทำให้คำอธิบายชัดเจนยิ่งขึ้นฉันชอบสิ่งนั้น + 1-ed ผู้ใช้อาจสร้างบางสิ่งที่คล้ายคลึงกับprintf "A\nB\nC\n" | tr 'ABC' '12'
Sergiy Kolodyazhnyy

18

trสำหรับการแปลอักขระไม่ใช่สำหรับคำที่สมบูรณ์ มันสามารถแปลชุด ในตัวอย่างของคุณคุณมี "nik-pc" เป็นตัวอักษรชุดแรกและ "root" เป็นอีกตัวหนึ่ง ที่จริงแล้วk-pเป็นช่วงดังนั้นจึงมีตัวอักษรทั้งหมดตั้งแต่ k ถึง p มันจะจับคู่ตัวอักษรทีละตัวดังนั้น n จะแปลเป็น r, i ถึง o, k ถึง o และสิ่งอื่น ๆ ที่นอกเหนือจากถ่านที่ 4 จะเป็น t นั่นเป็นเหตุผลที่คุณมี "เดสก์ท็อป" แปลเป็น "Desottt"

คุณสามารถดูได้ชัดเจนขึ้นในตัวอย่างนี้:

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

ที่นี่คุณสามารถเห็นtr ชุดที่ 1 มี D ในตำแหน่งที่ 4 แต่ชุดที่ 2 ไม่มีตำแหน่งที่ 4 ดังนั้นมันจะใช้ตำแหน่งสุดท้ายชุดที่ 2 ต้องแปล

สิ่งที่คุณกำลังทำคือการแปลคำหนึ่งเป็นอีกคำ สิ่งที่คุณต้องการจะทำคือการใช้เครื่องมือที่ทันสมัยมากขึ้นเช่นหรือsedawk

ตัวอย่างเช่น

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

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

1
คุณเร็วกว่าฉันมาก @Serg ... : P
ผู้บัญชาการ Byte

2
@ ByteCommander ฉันอาจได้รับรางวัลในความเร็ว แต่ฉันคิดว่าคำตอบของคุณชนะในคุณภาพ
Sergiy Kolodyazhnyy
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.