tr 如何将一个单词翻译成另一个单词?

tr 如何将一个单词翻译成另一个单词?

我有一个文件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

在第一行,它将“nik”替换为“too”,并将“Desktop”的拼写替换为“Desottt”。

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

答案1

tr用于翻译字符,而不是完整的单词。它可以翻译集合。在您的示例中,您有“nik-pc”作为第一个集合字符,而“root”是另一个。事实上,k-p是一个范围,因此它包括从 k 到 p 的所有字符。它将逐个匹配字符,因此 n 将转换为 r,i 转换为 o,k 转换为 o,而第 4 个字符以外的任何其他字符都将是 t。这就是为什么您将“Desktop”翻译成“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

答案2

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

您有nik-pc第一组。将其中的部分tr扩展k-p为从“k”到“p”范围内的所有字母,因此该集合等于niklmnopc

你的第二盘是root

现在要做tr的是搜索(已评估的)第一组中第一个字符的所有出现位置,并将其替换为第二组的第一个字符。当第二组中没有其他字符时,它只会重复其最后一个字符。请参阅下表:

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”标志以启用全局替换。如果没有这个标志,它只会替换每行的每个第一个匹配项。

相关内容