我对Linux shell的tr命令有两个疑问,①是:
$ echo 'abcd123' | tr -c 'a-z' '0-9'
结果为:'abcd9999',有4个'9',为什么?而且为什么是9,而不是'0-8'中的一个? ②是:
$ echo hello 1 char 2 next 4 | tr -d -c '0-9 \n'
结果是;' 1 2 4 ',有人能为我解释一下吗?它是如何执行的?
答案1
第一个问题:
echo 'abcd123'
实际上打印'abcd123\n'
到 stdout。至于tr -c 'a-z' '0-9'
选项-c
表示'a-z'
将使用 的补集进行翻译,请参阅 的手册页tr
。
除了 'az' 之外,还有很多字符对应于 '0-9',因此 中'abcd123\n'
除小写字母之外的其余字符,即'123\n'
,将被翻译为'9999'
。因此结果为 'abcd9999',末尾带有 '\n'。
第二个问题很简单:
echo hello 1 char 2 next 4
打印hello 1 char 2 next 4\n
到标准输出。'tr -d -c '0-9 \n''
删除每个'0-9'
数字和空格字符以及 '\n' 的补码。
这就是为什么剩下的字符包含数字和空格,以及尾随的“\n”。
答案2
关于命令:
echo 'abcd123' | tr -c 'a-z' '0-9'
的手册页tr
显示:
tr [OPTION]... SET1 [SET2]
...通过根据需要重复 SET2 的最后一个字符,将 SET2 的长度扩展为 SET1 的长度...
“az”的补码是除小写字母之外的所有字符。因此,该集合比“0-9”中的十个字符长很多,并且字符串“abcd123”中的数字与重复的最后一个字符“9”匹配。
在:
echo hello 1 char 2 next 4 | tr -d -c '0-9 \n'
您实际上告诉tr
删除您指定的 SET1 字符集中不包含的任何内容。因此,它会删除除数字、空格和换行符之外的所有字符。我不确定您还可能期望这里有什么。