我无法理解http://pubs.opengroup.org/onlinepubs/9699919799/utilities/tr.html的“理由”部分中的这一段。
ISO POSIX-2:1993标准的-c选项表现相似 到-C选项,但没有提供相当于的功能 POSIX.1-2008中指定的-c选项。这意味着能够指定tr -cd \ 000- \ 177的历史实践(将删除 设置最高位的所有字节都没有效果,因为在C中 语言环境,值为八进制200到八进制377的字节不是 字符。
但是,我对CentOS 6.5系统的测试似乎表明它似乎确实有效。
$ export LC_ALL=C
$ export LANG=C
$ locale
LANG=C
LC_CTYPE="C"
LC_NUMERIC="C"
LC_TIME="C"
LC_COLLATE="C"
LC_MONETARY="C"
LC_MESSAGES="C"
LC_PAPER="C"
LC_NAME="C"
LC_ADDRESS="C"
LC_TELEPHONE="C"
LC_MEASUREMENT="C"
LC_IDENTIFICATION="C"
LC_ALL=C
$ printf "\x41\x42\x81\x82" | od -t x1
0000000 41 42 81 82
0000004
$ printf "\x41\x42\x81\x82" | tr -c -d "\000-\1777" | od -t x1
0000000 41 42
0000002
命令tr -c -d "\000-\1777"
确实删除了值为\x81
和\x82
的字节。为什么我的测试结果不符合规范中的内容?
答案 0 :(得分:3)
由于您使用的是CentOS,因此您的tr
命令很可能来自GNU coreutils
包。 GNU tr
(尚未)区分-c
和-C
的行为。在tr
的最新版本中,-c
和-C
都是--complement
选项的等效短选项。
目前tr完全支持单字节字符。最终它将支持多字节字符;当它这样做时,-C选项将使它补充字符集,而-c将使它补充值集。仅当某些值不是字符时,此区别才有意义,并且仅当输入包含编码错误时,才可能在使用多字节编码的区域设置中进行此区分。
我还发现POSIX规范中引用的段落令人困惑,但我同意Etan Reisner的解释,即“符合1993版规范的实现将被破坏,但早期的实现(历史)和实现符合2008(及更新)规范将起作用。“
在任何情况下,GNU tr
都没有(还)实现2008 POSIX规范的这一部分(即区分字符和值),所以它不能用于测试。
顺便说一下,7
命令中有一个冗余的tr -c -d "\000-\1777"
。