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

在第一行,它用“ too”代替了“ nik”,“ Desktop”的拼写变成了“ Desottt”。

为什么是这样?它背后的逻辑是什么?


3
info coreutils 'tr invocation'告诉您详细信息tr
Nephente

4
顺便问一下你想做什么?该命令完全按照您的指示执行,但是我想您实际上想替换nik-pcroot
kos

3
第一步始终是检查命令的手册页。
Mostafa Ahangarha

1
@DavidZ:请注意,n它也在k-p范围内。POSIX未指定字符在第一组上出现多次的结果。
hmakholm在莫妮卡(Monica)

1
我认为您真正需要的是sed命令…… ls -l | sed 's/nik-pc/root/'会做您想要的。 tr用于转换单个字符-例如。小写到大写,或dos样式的lineshift(\ r)到Unix样式的(\ n),或诸如用斜杠替换所有反斜杠(Windows)之类的东西。它还可以删除“不需要的”字符,例如。所有数字或所有大写字母。
巴德·科佩鲁德

Answers:


16

tr按字符转换字符串。它从第一组中搜索字母,并用第二组中的字母替换。

你有过 nik-pc第一盘。trk-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版。用户可能会用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个char以外的任何其他字符均为t。这就是为什么您将“桌面”翻译为“ Desottt”的原因

在此示例中,您可以更清楚地看到它:

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

在这里,您可以看到tr 集合1在位置4上有D。但是集合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
或sed s / nik-pc / root / g ma.txt> ma2.txt
Bruni

1
你比我快得多@Serg ...:P
字节指挥官

2
@ByteCommander我可能已经赢得了速度,但是我认为您的回答会赢得质量
Sergiy Kolodyazhnyy
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.