1、用tr进行转换
tr是Unix命令行专家工具箱中的一件万能工具。它可用于编写优雅的单行命令。tr可以对来自标准输入的内容进行字符替换、字符删除以及重复字符压缩。tr是translate(转换)的简写,因为它可以将一组字符转换成另一组字符。
tr只能通过stdin(标准输入)接收输入(无法通过命令行参数接收)。其调用格式如下:
tr [options] set1 set2
- 来自stdin的输入字符会按照位置从set1映射到set2(set1中的第一个字符映射到set2中的第一个字符,以此类推),然后将输出写入stdout(标准输出)。set1和set2是字符类或字符组。
- 如果两个字符组的长度不相等,那么set2会不断复制其最后一个字符,直到长度与set1相同。
- 如果set2的长度大于set1,那么在set2中超出set1长度的那部分字符则全部被忽略。
# 将输入中的字符由大写转换成小写
echo "WHO IS THIS" | tr 'A-Z' 'a-z'
- 'A-Z'和'a-z'都是字符组。我们可以按照需要追加字符或字符类来构造自己的字符组。
- 'ABD-}'、'aA.,'、'a-ce-x'以及'a-c0-9'等均是合法的集合。定义集合也很简单,不需要书写一长串连续的字符序列,只需要使用“起始字符-终止字符”这种格式就行了。这种写法也可以和其他字符或字符类结合使用。
- 如果“起始字符-终止字符”不是有效的连续字符序列,那么它就会被视为含有3个元素的集合(起始字符、-和终止字符)。你也可以使用像'\t'、'\n'这种特殊字符或其他ASCII字符。
在tr中利用集合的概念,可以轻松地将字符从一个集合映射到另一个集合中,个用tr进行数字加密和解密的例子:
# 加密
echo 12345 | tr '0-9' '9876543210' # 87654
# 解密
echo 87654 | tr '9876543210' '0-9' # 12345
tr命令可以用来加密。ROT13是一个著名的加密算法。在ROT13算法中,字符会被移动13个位置,因此文本加密和解密都使用同一个函数:
# 下面命令会输出:ge pnzr, ge fnj, ge pbadhrerq.
echo "tr came, tr saw, tr conquered." | tr 'a-zA-Z' 'n-za-mN-ZA-M'
- t -> g:t 在 a-z 这个集合中是第 20 个字符,相应的 n-z 的第 20 个字符是 g
- r -> e:r 在 a-z 这个集合中是第 18 个字符,相应的 n-z 的第 18 个字符是 e
- 以此类推
2、用tr删除字符:-d
tr有一个选项-d,可以通过指定需要被删除的字符集合,将出现在stdin中的特定字符清除掉:stdin | tr -d '[set1]'
echo "Hello 123 World 456" | tr -d '0-9' # 输出:Hello World
3、字符组补齐:-c
使用选项 -c 来使用set1的补集(set2是可选的):tr -c [set1] [set2]
- 如果只给出了set1,那么tr会删除所有不在set1中的字符。
- 如果也给出了set2,tr会将不在set1中的字符转换成set2中的字符。
- 如果使用了-c选项,set1和set2必须都给出。
- 如果-c与-d选项同时出现,你只能使用set1,其他所有的字符都会被删除。
# 从输入文本中删除不在补集中的所有字符:结果输出—— 1 2 3
echo "hello 1 char 2 next 3" | tr -d -c '0-9 \n'
- '0-9 \n' 中的 \n 只是用来给标准输出换行的
# 将不在set1中的字符替换成空格:
echo hello 1 char 2 next 4 | tr -c '0-9 \n' ' '
4、用tr压缩字符:-s
tr可以删除字符串中重复出现的字符:tr -s '[需要被压缩的一组字符]'
# 在不删除重复字母的情况下去掉多余的空格
echo "GNU is not UNIX. Recursive right?" | tr -s ' '
# tr还可以用来删除多余的换行符:
cat multi_blanks.txt | tr -s '\n'
上面的例子展示了如何使用tr删除多余的'\n'字符。接下来让我们用tr以一种巧妙的方式将文件中的数字列表进行相加:
# 下面命令输出结果为 15
cat sum.txt | echo $[ $(tr '\n' '+') 0 ]
- 在命令中,tr命令将'\n'替换成了'+',我们因此得到了字符串1+2+3+..5+,但是在字符串的尾部多了一个操作符+。为了抵消这个多出来的操作符,我们再追加一个0。
- $[ operation ]执行算术运算,因此就形成了以下命令:
echo $[ 1+2+3+4+5+0 ]
- 如果我们利用循环从文件中读取数字,然后再进行相加,那肯定得用几行代码。有了tr,只用一行就搞定了。
如果有一个包含字母和数字的文件,我们想计算其中的数字之和,这需要更强的技巧性:
# 利用tr的-d选项删除文件中的字母,然后将空格替换成+:
cat test.txt | tr -d [a-z] | echo "total: $[$(tr ' ' '+')]" # 输出结果为 6
5、tr支持的字符类
可以按照下面的方式选择所需的字符类:tr [:class:] [:class:]
tr '[:lower:]' '[:upper:]'
tr可以将不同的字符类作为集合使用
alnum:字母和数字。 | alpha:字母。 |
cntrl:控制(非打印)字符。 | digit:数字。 |
graph:图形字符。 | lower:小写字母。 |
print:可打印字符。 | punct:标点符号。 |
space:空白字符。 | upper:大写字母。 |
xdigit:十六进制字符。 |