Chinaunix首页 | 论坛 | 博客
  • 博客访问: 402431
  • 博文数量: 105
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 889
  • 用 户 组: 普通用户
  • 注册时间: 2016-01-23 21:45
个人简介

目前在一家电信公司就职报表开发工程师,2010年开始从事运维方面的工作,期间从事过业务维护工程师、自动化运维工程师,2016年转为报表开发工程师。有耐心,抗压力、爱折腾,喜欢研究自动化工具。

文章分类

全部博文(105)

分类: LINUX

2017-08-23 23:37:48

原文地址:shell脚本中的tr用法 作者:kouyanghao

tr 用来从标准输入中通过替换或删除操作进行字符转换。
tr 主要用于删除文件中控制字符或进行字符转换。
使用tr时要转换两个字符串:
字符串1用于查询字符串2用于处理各种转换
tr刚执行时,字符串1中的字符被映射到字符串2中的字符,然后转换操作开始。

带有最常用选项的t r命令格式为:
tr -c -d -s[ "string1_to_translate_from" ] [ "string2_to_translate_to" ] input_file
-c 
用字符串1中字符集的补集替换此字符集,要求字符集为ASCII。
-d 删除字符串1中所有输入字符。
-s 删除所有重复出现字符序列,只保留第一个;即将重复出现字符串压缩为一个字符串。
Input-file是转换文件名。虽然可以使用其他格式输入,但这种格式最常用。

字符范围
使用tr时,可以指定字符串列表或范围作为形成字符串的模式。这看起来很像正则表达式,但实际上不是。指定字符串1或字符串2的内容时,只能使用单字符或字符串范围或列表。
[a-z] a-z内的字符组成的字符串
[A-Z] A-Z内的字符组成的字符串
[0-9] 数字串
/octal 一个三位的八进制数,对应有效的ASCII字符
[O*n] 表示字符O重复出现指定次数n 如:[O*2]匹配OO的字符串。
大部分tr变种支持字符类速记控制字符
字符类格式为[:class],包含数字、希腊字母、空行、小写、大写、ctrl键、空格、点记符、图形等等。

下面包括最常用的控制字符的速记方式及三位八进制引用方式。
当用一个单字符替换一个字符串或字符范围时,注意字符并不放在方括号里([ ])。一些系统也可以使用方括号,例如可以写成["\012"]或"\012",tr也允许不加引号,因此命令中看到单引号而不是双引号时也不要感到奇怪。
像大多数系统工具一样, tr也受特定字符的影响。因此如果要匹配这些字符,需使用反斜线屏蔽其特殊含义。例如,用\{ 指定花括号左边可以屏蔽其特殊含义。

tr中特定控制字符的不同表达方式
速记符含义八进制方式

\a   Ctrl-G   铃声      \007
\b   Ctrl-H   退格符    \010
\f   Ctrl-L   走行换页  \014
\n   Ctrl-J   新行      \012
\r   Ctrl-M   回车      \015
\t   Ctrl-I   tab键     \011
\v   Ctrl-X             \030

 
去除重复出现的字符 
下面文件包含了一些打印错误。这种情况时常发生,例如在vi编辑器中,偶尔按住一个键不放。  
[sam@chenwy split]$ cat opps.txt 
And the cowwwwws went homeeeeeeeeeeeee 
Or did theyyyyyyyyyyyyy 
如果要去除重复字母或将其压缩在一起,使用-s选项。因为都是字母,故使用[a-z]。输入文件重定向到tr命令。
[sam@chenwy split]$ tr -s "[a-z]" < opps.txt 
And the cows went home 
Or did they 
所有重复字符被压缩成一个。如果使用cat命令,再将结果管道输出至tr,结果是一样的。  
[sam@chenwy split]$ cat opps.txt | tr -s "[a-z]" 
And the cows went home 
Or did they


删除空行 
要删除空行,可将之剔出文件。下面是一个文件plane.txt。文本间有许多空行。  
[sam@chenwy split]$ cat plane.txt 
9879932 Spitfire  


190992 Lancaster


238991 Typhoon


使用-s来做这项工作。换行的八进制表示为\012,命令为: 
[sam@chenwy split]$ tr -s "[\012]" < plane.txt 
9879932 Spitfire 
190992 Lancaster 
238991 Typhoon

也可以使用换行速记方式\n。 
[sam@chenwy split]$ tr -s "[\n]" < plane.txt 
9879932 Spitfire 
190992 Lancaster 
238991 Typhoon


大写到小写 
除了删除控制字符,转换大小写是tr最常用的功能。为此需指定即将转换的小写字符[a-z]和转换结果[A-Z]。 
第一个例子,tr从一个包含大小写字母的字符串中接受输入。 
[sam@chenwy split]$ echo "May Day,May Day,Going Down.." | tr "[a-z]" "[A-Z]" 
MAY DAY,MAY DAY,GOING DOWN.. 
同样,也可以使用字符类[:lower:][:upper:]。 
[sam@chenwy split]$ echo "May Day,May Day,Going Down.." | tr "[:lower:]" "[:upper:]" 
MAY DAY,MAY DAY,GOING DOWN..

 

删除指定字符
偶尔会从下载文件中删除只包含字母或数字的列。需要结合使用-c-s选项完成此功能。
下面的文件包含一个星期的日程表。任务是从其中删除所有数字,只保留日期。日期有大写,也有小写格式。因此需指定两个字符范围[a-z]和[A-Z],命令tr -cs "[a-z][A-Z]""[\012*]"将文件每行所有不包含在[a-z]或[A-Z](所有希腊字母)的字符串放在字符串1中并转换为一新行。-s选项表明压缩所有新行, -c表明保留所有字母不动。原文件如下,后跟tr命令:
[sam@chenwy split]$ cat diary.txt

mondy 10:50

Tuesday 15:00

wednesday 15:30

thurday 10:30

Fridya 09:20
[sam@chenwy split]$ tr -cs "[a-z][A-Z]" "[\012*]" < diary.txt

mondy

Tuesday

wednesday

thurday

Fridya


转换控制字符
tr的第一个功能就是转换控制字符,特别是从dos向Unix下载文件时,忘记设置ftp关于回车换行转换的选项时更是如此。
下面是故意没有设置转换开关的一个文本文件,是关于文具需求的一部分内容。使用cat -v显示控制字符。
[sam@chenwy split]$ cat -v stat.tr

Boxes paper     12^M

Clips metal     50^M

Pencils-meduim  10^M

^Z
猜想‘中间空的是’是tab键。每一行以ctrl -M结尾,文件结尾ctrl - Z,以下是改动方法。
使用-s选项,查看ASCII表^的八进制代码是136,^ M是015,tab键是011,^Z是032 ,下面将按步骤完成最终功能。

用新行替换每行末尾的^M,并用\n去除^Z,输入要来自于临时工作文件stat.tmp。将结果重定向到临时工作文件stat.tmp。
[sam@chenwy split]$ tr -s "[\015\032]" "\n" stam.tmp

[sam@chenwy split]$ cat -v stam.tmp

Boxes paper     12

Clips metal     50

Pencils-meduim  10
快速转换
如果需要删除文件中^M,并代之以换行。使用命令:
[sam@chenwy split]$ tr -s "[\015]" "\n" < stat.tr |cat -v

Boxes paper     12

Clips metal     50

Pencils-meduim  10

^Z
或者用下述命令得同样结果。
[sam@chenwy split]$ tr -s "[\015]" "\n" < stat.tr >stat1.tr

[sam@chenwy split]$ cat stat1.tr

Boxes paper     12

Clips metal     50

Pencils-meduim  10
也可以用下述命令:
[sam@chenwy split]$ tr -s "[\r]" "\n" < stat.tr
[sam@chenwy split]$ tr -s "\r" "\n" < stat.tr 
另一个一般的dos到Unix转换是命令:
[sam@chenwy split]$ tr -s "[\015\032]" "[\012*]" < stat.tr

Boxes paper     12

Clips metal     50

Pencils-meduim  10
将删除所有^M和^Z,代之以换行。

要删除所有的tab键,代之以空格,使用命令:
[sam@chenwy split]$ tr -s "[\011]" "[\040*]" < stat.tr >temp.txt

[sam@chenwy split]$cat -v temp.txt

Boxes paper 12^M

Clips metal 50^M

Pencils-meduim 10^M

^Z
替换passwd文件中所有冒号,代之以tab键,可以增加可读性。将冒号引起来,指定替换字符串中tab键八进制值011,下面是passwd文件,后跟tr命令结果:
[sam@chenwy split]$ tr -s "[:]" "[\t]" < passwd

root    x       0       0       root    /root   /bin/bash

bin     x       1       1       bin     /bin    /sbin/nologin

daemon  x       2       2       daemon  /sbin   /sbin/nologin

.....................

[sam@chenwy split]$ tr -s "[:]" "[\011]" < passwd

匹配多于一个字符
可以使用[character*n]格式匹配多于一个字符。下述文件列出系统硬盘信息,其中包含了系统已经注册的和未识别的。第一列是数字,如果不全是0,表明第二列相应硬盘已经注册。
有时全部为0看起来很烦人,找个吸引人注意力的符号来代替它,以便一眼就能看出哪个硬盘已注册,哪个不可识别。原文件如下:
[sam@chenwy split]$ cat hdisk.txt

15566 hdisk3

456554 hdisk2

0000 hdisk1
从文件列表中知道,有一个硬盘未注册,因此用星号代替所有的0。模式为[0*4],意即匹配至少4个0,替换字符串为星号,过滤命令及结果如下:
[sam@chenwy split]$ tr "[0*4]" "*" < hdisk.txt

15566 hdisk3

456554 hdisk2

**** hdisk1
但我发现加上[]后结果不对了
[sam@chenwy split]$ tr "[0*4]" "[*]" < hdisk.txt

15566 hdisk3

456554 hdisk2

]]]] hdisk1

阅读(3077) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~