linux常用命令—tr

tr—字符串、文本转换工具

基础用法

tr主要用于字符串和文本内容的替换和删除,但不改变原字符串或文本。

语法:命令输出 | tr 选项 [SET1] [SET2]tr 选项 [SET1] [SET2] < 处理文件

其中SET1为被替换或删除的字符集,SET2为要替换成的字符集,均支持正则表达式。

选项:

默认:替换(映射)所有

-c:反向替换(映射),即替换(映射)SET1的补集

-d:删除SET1

-s:去重SET1并替换(映射)为SET2

-t :截断SET1超出SET2长度的部分后再替换(映射)

 

命令详解:

1. 默认选项

[lsc@localhost ~]$ cat test.sh
I love cats.
I love rabbits.
I love camels.
[lsc@localhost ~]$ tr cat dog < test.sh
I love dogs.
I love robbigs.
I love domels.

发现tr并不是简单地将文本中的所有SET1替换为SET2,而是将SET1中的每一个字符替换为对应的SET2中的字符,此处即是将文本中所有的c替换为d,a替换为o,t替换为g,像一种一一映射的关系,但如果SET1的长度与SET2的长度不一致呢?

(1)SET1 > SET2 —— SET1多出来的字符映射为SET2最后一个字符

[lsc@localhost ~]$ tr cat do < test.sh
I love doos.
I love robbios.
I love domels.

(2)SET1 < SET2 —— SET2多出来的字符无效

[lsc@localhost ~]$ tr ca dog < test.sh
I love dots.
I love robbits.
I love domels.

(3)SET1中有重复字符 —— 以SET2最后一次映射的为准

[lsc@localhost ~]$ tr caa dog < test.sh
I love dgts.
I love rgbbits.
I love dgmels.

常用用法——文本字符大小写替换:

例如将test.sh中的所有小写字符替换为大写字符:

[lsc@localhost ~]$ tr a-z A-Z < test.sh
I LOVE CATS.
I LOVE RABBITS.
I LOVE CAMELS.

还可以用tr内置的变量[:lower:]和[:upper:](注意两者必须同时使用,否则会报错)

[lsc@localhost ~]$ tr [:lower:] [:upper:] < test.sh
I LOVE CATS.
I LOVE RABBITS.
I LOVE CAMELS.

 

2. -c选项

[lsc@localhost ~]$ tr -c cat dog < test.sh
gggggggcatgggggggggggagggtggggggggggcagggggg[lsc@localhost ~]$

-c选项的SET2只有最后一个字符是有效的,会将文本中除了SET1的所有字符替换为SET2的最后一个字符,这里包括文本最后的一个换行符,所以会发现Linux控制台前缀会出现在输出结果的后面,而不是另起一行。

再举一例:

[lsc@localhost ~]$ echo "abc" | tr -c a @
a@@@[lsc@localhost ~]$ 

这里使用-c反向替换echo输出的字符串后,Linux控制台前缀也会跟在命令输出结果的后面而非另起一行,而且明明原来字符串只有"abc"三个字符,替换后变成了四个字符,这也是因为echo命令总是会自带输出一个换行符到其右的字符串末尾,而字符串+换行符都会通过管道传给tr命令,所以这里tr命令真正处理的是管道传给它的"abc”三个字符加末尾一个换行符(这一点常常会被忽略,因为我们是用自己的视角看,而不是从tr命令的视角看)。

同理用默认正向替换尝试:

[lsc@localhost ~]$ echo "abc" | tr "\n" @
abc@[lsc@localhost ~]$ 

注意这里换行符\n可用双引号包裹,也可用单引号包裹:

[lsc@localhost ~]$ echo "abc" | tr \n @
abc@[lsc@localhost ~]$ 

或者再加一个反斜杠转义一下换行符自己的反斜杠:

[lsc@localhost ~]$ echo "abc" | tr \\n @
abc@[lsc@localhost ~]$ 

这里容易出错:Linux换行符\n,是两个字符缺一不可,但是Linux控制台上的反斜杠总是会自动与其后一个字符结合,自身消失变成一个新字符,所以必须加引号防止其拓展(单引号只需括反斜杠‘\‘,双引号要把"\n"全部括起来),或者在前面再加一个反斜杠先转义了换行符的反斜杠,使其在控制台上保留下来,再与n一起表示一个换行符。

 

3. -d选项

 -d选项删除SET1,只需要SET1即可:

[lsc@localhost ~]$ echo "abc" | tr -d ab
c

 

4. -s选项

-s选项可以不加SET2,只做去重操作,将文本中SET1重复的部分删除:

[lsc@localhost ~]$ echo "aabbbcccc" | tr -s abc
abc

加上SET2,则先对SET1进行去重,再将去重后的SET1映射为SET2:

[lsc@localhost ~]$ echo "aabbbcccc" | tr -s abc 123
123

常用用法——去除文件中多余的空行、空格、制表符:

[lsc@localhost ~]$ cat test2.sh

I love drumsticks.

        Drumsticks is delicious.


  Are you love Drumsticks?

[lsc@localhost ~]$ 
[lsc@localhost ~]$ tr -s "\n\t " < test2.sh

I love drumsticks.
    Drumsticks is delicious.
 Are you love Drumsticks?
[lsc@localhost ~]$ 

发现-s选项在删除多余换行符的时候似乎达到了我们删除文件空行的效果(除了文本开头的空行,但它也不算多余的空行),简化一下这里的test2.sh文本(可以用echo -e输出到文件中试下):

"\nstr1\n\n\t\tstr2\n\n\n  str3\n\n"

-s选项处理后的结果:

"\nstr1\n\tstr2\n str3\n"

这样就一目了然了,同时也解释了为什么不能使用-d选项删除文本中的空行(会使原来在两行的文本挤到同一行来)。

小拓展:对于特殊的字符可以使用Linux的ASCII码进行tr操作(man ascii命令查看):

换行符(\n)——012

制表符(\t)——011

空格符(SPACE)——040

上面举例的命令可以替换为:

tr -s "\012\011\040" < test2.sh

 

5. -t选项

-t选项会截断SET1超出SET2长度的部分然后再做正向映射:

[lsc@localhost ~]$ echo "abc" | tr -t ab @
@bc

linux常用命令—tr

上一篇:Linux之JDK的安装部署


下一篇:给 Linux 命令行工具配置代理