SHELL脚本攻略(学习笔记)--2.5 tr

tr主要用于映射结果集、压缩和删除字符。我个人感觉特别有用,特别是压缩连续空格(空行)为一个空格(空行),让不规则的信息变得规则。

2.5.1 tr映射

tr [options] [SET1] [SET2]

如果同时指定了SET1和SET2,则实现的是将SET1的符号按位置一一对应映射为SET2中的符号。实际上就是对应替换。

tr接收到stdin后首先会把标记意义上的符号替换为换行符,然后才执行指定的选项参数。什么是标记意义上的符号请看xargs的内容http://www.cnblogs.com/f-ck-need-u/p/5925923.html

例如:

[[email protected] tmp]# ls

a  b  c  d  logdir  one  one space.log  shdir  sh.txt  space.log  test  vmware-root

[[email protected] tmp]# ls | tr " " "\t"  ç由于先替换为换行符,所以有且只有一个文本意义上的空格被替换为制表符

a

b

c

d

logdir

one

one     space.log

shdir

sh.txt

space.log

test

vmware-root

如果在SET1中使用了\n,会发现最后的结果中是紧接着命令提示符。就像下面的。这就是因为原本最后一行的尾部是有分行符的,替换之后就没有了分行符。

[[email protected] tmp]# echo {1..10} | tr "\n" "x"

1 2 3 4 5 6 7 8 9 10x[[email protected] tmp]#

之所以说tr是映射而不是替换,是因为两个结果集替换的时候符号位置是一一对应的。例如下面例子的第二条命令,因为\n是SET1中的唯一一个也是第一个符号位,所以SET2中只取第一个符号位“X”进行替换。Y字符就被忽略了。

[[email protected] tmp]# ls | tr "\n" "X"

aXbXcXdXlogdirXoneXone space.logXshdirXsh.txtXspace.logXtestXvmware-rootX

[[email protected] tmp]# ls | tr "\n" "XY"

aXbXcXdXlogdirXoneXone space.logXshdirXsh.txtXspace.logXtestXvmware-rootX

那么这样就可以实现简单的加密和解密了。

[[email protected] tmp]# echo "12345" | tr "0-9" "9876543210"     ç加密

87654

[[email protected] tmp]# echo "87654" | tr "0-9" "9876543210"     ç解密

12345

上面的过程是将管道左边的12345对应到0-9的展开式0123456789,并将对应位映射到SET2的数字上。解密也是同理。

更典型的是ROT13加密算法,它的加密和解密使用一套字符。它的SET1的字母位和SET2的字母位完全反向成对。例如SET1指定符号是“axy”,如果SET2想将其对应为“opq”,则须将SET1扩展为“axyopq”,SET2扩展为“opqaxy”,最终是(a,x,y,o,p,q)和(o,p,q,a,x,y),这样(a,o)和(o,a)就配对了,无论加密还是解密都能使用这一套字符。将其扩展为A-Z和a-z就是ROT13加密,甚至还可以将0-9也加上去和9-0对应。下面是SET1和SET2的对应式。

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz

NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm

现在加密“I love you”

[[email protected] tmp]# echo "I love you" | tr "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" "NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm"

V ybir lbh

将“V ybir lbh”解密。

[[email protected] tmp]# echo "V ybir lbh" | tr "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" "NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm"

I love you

2.5.2 完全对应的替换

默认情况下,当指定的SET1比SET2字符长时,从最后一个对应的位置开始,SET1的剩余字符都和SET2的最后一个字符对应。假如SET1=[1234],SET2=[abc],则3对应c,4也对应c,此时如果tr的操作对象中出现3或者4都会被替换为c。

使用-t可以先截断SET1比SET2中长的字符,例如上面截断多余的4,SET1=[123]和SET2=[abc]就实现了完全对应。

[[email protected] tmp]# cat x.txt

NO Name SubjectID Mark 备注

1  longshuai 001  56 不及格

2  gaoxiaofang  001 60 及格

3  zhangsan 001 50 不及格

4  lisi    001   80 及格

5  wangwu   001   90 及格

[[email protected] tmp]# cat x.txt | tr  "fang" "jin"   ç结果中n和g都被替换为了n

NO Nime SubjectID Mirk 备注

1  lonnshuii 001  56 不及格

nioxiiojinn  001 60 及格

3  zhinnsin 001 50 不及格

4  lisi    001   80 及格

5  winnwu   001   90 及格

[[email protected] tmp]# cat x.txt | tr  -t "fang" "jin"  çg被截断,只对应替换fan为jin

NO Nime SubjectID Mirk 备注

1  longshuii 001  56 不及格

gioxiiojing  001 60 及格

3  zhingsin 001 50 不及格

4  lisi    001   80 及格

5  wingwu   001   90 及格

2.5.3 压缩符号

这功能太爽了。

tr -s [SET1] [SET2]

它可以将指定的连续的SET1的第一个符号压缩并替换为SET2中的第一个,如果不指定SET2就仅仅只压缩。这样可以使结果变得具有固定的格式,传递给其他命令进行文本处理时就方便太多了。

假如x.txt文件中的内容如下,空格有的地方多,有的地方少,也就是说是一个没有格式的文件。

[[email protected] tmp]# cat x.txt

NO Name SubjectID Mark 备注

1  longshuai 001  56 不及格

2  gaoxiaofang  001 60 及格

3  zhangsan 001 50 不及格

4  lisi    001   80 及格

5  wangwu   001   90 及格

使用tr压缩空格使其变的规则。

[[email protected] tmp]# cat x.txt | tr -s “" "

NO Name SubjectID Mark 备注

1 longshuai 001 56 不及格

2 gaoxiaofang 001 60 及格

3 zhangsan 001 50 不及格

4 lisi 001 80 及格

5 wangwu 001 90 及格

如果指定SET2,假如替换为-。

[[email protected] tmp]# cat x.txt | tr -s " " "-"

NO-Name-SubjectID-Mark-备注

1-longshuai-001-56-不及格

2-gaoxiaofang-001-60-及格

3-zhangsan-001-50-不及格

4-lisi-001-80-及格

5-wangwu-001-90-及格

如果指定的SET1或SET2超过1个字符,则两者都只取第一个字符。例如x.txt中的Mark列有两个连续的0,将其替换为a。

[[email protected] tmp]# cat x.txt | tr -s “"00" "aa"

NO Name SubjectID Mark 备注

1  longshuai a1  56 不及格

2  gaoxiaofang  a1 6a 及格

3  zhangsan a1 5a 不及格

4  lisi    a1   8a 及格

5  wangwu   a1   9a 及格

2.5.4 删除符号和补集

tr -d是删除指定的符号,只能接一个SET1。

[[email protected] tmp]# cat x.txt | tr -d " "

NONameSubjectIDMark备注

1longshuai00156不及格

2gaoxiaofang00160及格

3zhangsan00150不及格

4lisi00180及格

5wangwu00190及格

tr -c SET1 SET2是求tr操作对象对SET1的补集,然后将补集字符全部替换为SET2。即将tr操作对象中不在SET1中存在的字符替换为SET2的字符。但是SET2如果指定的字符大于1个,则只取最后一个字符作为替换字符。使用-c的时候应该把-c SET1作为一个整体,不要将其分开。

例如:

[[email protected] tmp]# echo "abcdefo"| tr -c "ao" "y"

ayyyyyoy[[email protected] tmp]#

上面的是把“abcdefo”除ao的替换为y,即ayyyyyo,但是结果的最后面多了一个y并且紧接着命令提示符。这是因为abcdefo尾部的\n也是ao的补集的一部分,并将其替换为y了。如果不想替换最后的\n,可以在SET1中指定\n。

[[email protected] tmp]# echo "abcdefo"| tr -c "ao\n" "y"

ayyyyyo

如果SET2指定多个字符,将只取最后一个字符作为替换字符。

[[email protected] tmp]# echo "abcdefo"| tr -c "ao\n" "ay"

ayyyyyo

[[email protected] tmp]# echo "abcdefo"| tr -c "ao\n" "yb"

abbbbbo

-c常和-d一起使用,tr -d -c SET1。它先执行-c SET1求出tr操作对象对SET1的补集,再对这个补集执行删除,也就是说最终的结果是SET1类的。注意,-d一定是放在-c前面的,否则执行的就不是删除补集,而是替换补集为-d的最后一个字符d了。

[[email protected] tmp]# echo "one 1 two 2 three 3"| tr -d -c "[0-9]\n"      ç对数字和分行符求补集,并删除这些补集符号

123

[[email protected] tmp]# echo "one 1 two 2 three 3"| tr -d -c "[0-9] \n"     ç多对一个空格求补集,这样结果中就保留空格了

1  2  3

[[email protected] tmp]# echo "one 1 two 2 three 3"| tr -c "[0-9]\n" -d      ç -d选项放在-c选项的后面是替换行为

dddd1ddddd2ddddddd3

[[email protected] tmp]# echo "one 1 two 2 three 3"| tr -d -c "[a-zA-z]\n"   ç保留字母

onetwothree

[[email protected] tmp]# echo "one 1 two 2 three 3"| tr -d -c "[a-zA-z] \n"  ç保留字母的同时保留空格

one  two  three

从上面补集的实验中可以看到,其实指定的[0-9]和[a-z]是一个类,最终的结果显示的是这个类中的对象。

在tr中可以使用以下几种类。这些类也可以用在其他某些命令中。

[:alnum:]所有的数字和字母

[:alpha:]所有的字母

[:blank:]所有水平空白=空格+tab

[:cntrl:]所有控制字符(非打印字符),在ascii表中的0-37对应的字符和127的del

[:digit:]所有数字

[:graph:]所有打印字符,不包含空格=数字+字母+标点

[:lower:]所有小写字母

[:print:]所有打印字符,包含空格=数字+字母+标点+空格

[:punct:]所有标点符号

[:space:]所有水平或垂直空白=空格+tab+分行符+垂直tab+分页符+回车键

[:upper:]所有大写字母

[:xdigit:]所有十六进制数字

使用方法例如下面的。例如[:upper:]等价于[A-Z],[:digit:]等价于[0-9]。

[[email protected] tmp]# echo "one ONE 1 two TWO 2 three THREE 3" | tr -d -c "[:upper:] \n"

ONE   TWO   THREE

[[email protected] tmp]# echo "one ONE 1 two TWO 2 three THREE 3" | tr -d -c "[:alpha:] \n"

one ONE  two TWO  three THREE

[[email protected] tmp]# echo "one ONE 1 two TWO 2 three THREE 3" | tr -d -c "[:digit:] \n"

1   2   3

时间: 2024-08-01 03:04:34

SHELL脚本攻略(学习笔记)--2.5 tr的相关文章

SHELL脚本攻略(学习笔记)--1.7 expr命令全解

expr命令可以实现数值运算.数值或字符串比较.字符串匹配.字符串提取.字符串长度计算等功能.它还具有几个特殊功能,判断变量或参数是否为整数.是否为空.是否为0等. 先看expr命令的info文档info coreutils 'expr invocation'的翻译. 16.4.1 字符串表达式 ------------------------- 'expr'支持模式匹配和字符串操作.字符串表达式的优先级高于数值表达式和 逻辑关系表达式. 'STRING : REGEX' 执行模式匹配.两端参数

SHELL脚本攻略(学习笔记)--1.6 数学运算和bc命令

本文目录: 1.6.1 基本整数运算 1.6.2 bc命令高级算术运算 使用let.$(())或$[]进行基本的整数运算,使用bc进行高级的运算,包括小数运算.其中expr命令也能进行整数运算,还能判断参数是否为整数,具体用法见expr命令全解. 1.6.1 基本整数运算 [[email protected] tmp]# str=10 [[email protected] tmp]# let str=str+6 # 等价于let str+=6 [[email protected] tmp]# l

《Linux Shell脚本攻略》 笔记 第一章:Shell起步基础

<Linux Shell脚本攻略> 笔记 第一章:Shell起步基础 1.变量:在bash中,每一个变量的值都是字符串.无论你给变量赋值时,有没有使用引号,值都会以字符串的形式存储. 2.var=value; //赋值操作 var = value: //相等操作 3.获取字符串的长度 [[email protected] ~]$ var=yang [[email protected] ~]$ length=${#var} [[email protected] ~]$ echo $length

《Linux Shell脚本攻略》 笔记 第二章:常用命令

<Linux Shell脚本攻略> 笔记 第二章:常用命令 1.cat cat -s //多个空白行压缩成一个 cat *.txt | tr -s '\n'   //移除空白行 cat -n //加行号 2.find 沿着文件层次结构向下遍历,匹配符合条件的文件,并执行相应的操作. eg: find ./ ! -name "*.txt" -print [[email protected] program_test]# find ./  -type f -name "

《Linux Shell脚本攻略》 笔记 第三章:文件操作

<Linux Shell脚本攻略> 笔记 第三章:文件操作 1.生产任意大小的文件 [[email protected] dd_test]# [[email protected] dd_test]# dd if=/dev/zero of=junk.data bs=1k count=10 10+0 records in 10+0 records out 10240 bytes (10 kB) copied, 0.00137023 s, 7.5 MB/s 2.文件系统相关测试 [ -f $file

《Linux Shell脚本攻略》 笔记 第四章:高效文本处理

<Linux Shell脚本攻略> 笔记 第四章:高效文本处理 1.IP地址的正则表达式: [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} 2.grep用法 //在多级目录中对文本进行递归检索 [[email protected] program_test]# grep "yang" ./ -Rn ./test.txt:6:laoyang ./right.txt:1:1 yang man //忽略大小写匹配 [[email pr

《Linux Shell脚本攻略》 笔记 第六章:打包压缩

<Linux Shell脚本攻略> 笔记 第六章:打包压缩 //1.打包.解包 [[email protected] program_test]# tar -cf output.tar 11.txt 22.txt 33.txt [[email protected] program_test]# tar -xf output.tar -C ./tar-file/  //-C指定要提取到哪个路径? //列举出归档文件中的内容 [[email protected] program_test]# ta

Linux Shell 脚本攻略阅读笔记第1章 小试牛刀

一.简介 1.Bash(Bourne Again Shell),目前大多数GNU/Linux系统默认的shell环境. 命令都是在shell终端中输入并执行.打开终端后,提示符的形式:[email protected]$       或    [email protected] #     ($表示普通用户,#表示管理员用户root) 2.shell脚本是一个以#!(shebang)起始的文本文件,如下:   #!/bin/bash shebang是一个文本行,其中#!位于解释器路径之前./bi

LINUX SHELL脚本攻略笔记[速查]

Linux Shell脚本攻略笔记[速查] 资源 shell script run shell script echo printf 环境变量和变量 pgrep shell数学运算 命令状态 文件描述符和重定向 cat 数组和关联数组 alias date 调试脚本 函数和参数 管道 读取命令输出 read 字段分隔符和迭代器 循环 比较和测试 find xargs tr md5sum sha1sum 对目录进行校验 sort uniq tempfile split bash变量匹配切分 exp

Linux Shell脚本攻略(1.12)

1.12 函数和参数 和其他脚本语言一样,Bash同样支持函数,并且可以传递参数. 1.12.1 函数定义和传参 #!/bin/bash function fname() #也可以用fname()代替 { echo $1,$2; #访问参数1和参数2 echo "[email protected]"; #以列表的方式一次性打印所有参数 echo "$*"; #类似于[email protected],但是参数被作为单个实体 return 0; #返回值 } fnam