11 November 2013

相信大家都知道一种最简单的加密方法,即根据映射表映射。比如收到a,查表得到某个字母,比如d吧。这样就完成解密的过程。在linux下无论加密还是解密都仅仅需要一行命令:

echo  "adbcbcd" | tr 'abcd' 'defg'
echo "deffffg" | tr 'defg' 'abcd' 

这便是今天要介绍一个非常神奇的工具——tr。tr的主要作用是将一组数据通过一定的规则映射另一组数据。如果两组数据长度不等,假设set1比set2长,set2会不断重复其最后一个字符,直到长度与set1相同。如果set2比set1长,则set2中超出set1的部分字符将被全部忽略。另外tr是无法通过命令行参数来接受输入的。来看看tr的基本形式:

tr [option] set1 set2

来看看那个加密方法是怎么回事。首先通过管道“adbcbcd”被传给tr(tr不能直接接受输入,要通过管道)。tr将“abcd”映射为“defg”,是一一对应的,若长度不等,上面已经介绍了处理方法。解密过程同理。

再比如大小写转换:

echo "HELLOWORLD" | tr 'A-Z' 'a-z'
helloworld

A-Z即从ABC…Z。小写调换一下位置即可。接下来看看只有一个set的用法:

echo "hello 123 world 456" | tr -d '0-9'
"hello world " 
echo "hello 123 world 456" | tr -d -c '0-9\n'
123456
echo "helloooo 123 world 456" | tr -s 'o'
"hello 123 world 456" 

“-d”选项指删除,这里是删除所有数字。“-c”选项是保留那些部分,这里保留了数字和换行符。-s则是删除指定的重复字符,这里删除重复的’o’(保留一个)。

有一种“过滤”的感觉,其实tr还有很有趣的用法:

cat num.txt
1
2
3

cat num.txt | echo $[  $(tr '\n' '+') 0 ]
6

很神奇是吧。首先tr先把换行符替换为’+’。其次由于3后面有一个换行符被替换为’+’,则在最后填一个0,使得其变成1+2+3+0。通过echo $[1+2+3+0]实现加法。

刚才说到大小写转换,其实还有一种方法:

echo "HELLOWORLD" | tr [:upper:] [:lower:]
helloworld

冒号中间的参数可以换成其他的:

alnum  字母和数字
alpha  字母
cntrl  控制字符
digit  数字
graph  图形字符
lower  小写字母
upper  大写字母
print  可打印字符
punct  逗号
space  空格
xdigit 十六进制字符

再举个例子:

echo "abcdefgxyz123" | tr [:lower:] [:digit:]
0123456999123
echo "abcdefgxyz123" | tr [:alpha:] [:digit:]
9999999999123

第一行由于小写字母有26个,而数字只有十个,所以前10个字母被映射为0到9,其他的只能是9,与前面的做法一样。第二行的命令也很明显,大写字母就已经把0到9排完了,剩下的只能映射9。

tr需要配合其他命令,相信它绝对是你不可多得的好工具。



blog comments powered by Disqus