-1

我对选项的执行顺序感到困惑tr

例如,有这样一个命令:

echo 123 | tr -ct '\n' '0'

这是如何执行的?是-c先执行还是-t

我也对这个命令的结果感到困惑。我以为-c是先执行,结果是123,然后-t会执行,结果是023,最后是023\n。但这是错误的,正确的答案是123\n,我不知道为什么,有人可以告诉我吗?

4

2 回答 2

0

有趣的是,tr -ct似乎补充了第一组,然后将其截断到第二组的长度。这可能不是您应该依赖的行为,因为-t它“首先将 SET1 截断为 SET2 的长度”。

无论如何,明显的效果是-c首先应用,将第一个集合\n转换为包含每个字符的集合,但\n按升序排序(因此第一个字符是 NUL 字符\0)。然后,-t应用 ,导致集合被截断为\0。因此,tr会将 NUL 字符转换为0字符。

例如,考虑一下:

$ tr --version
tr (GNU coreutils) 8.13
$ echo -e 'X\0X'
XX
$ echo -e 'X\0X' | tr -ct '\n' '0'
X0X
于 2013-08-24T13:28:19.557 回答
0

-c 表示使用 string1 中字符的补码,或者“任何不在 string1 中的字符替换 string1 的值”。

-t 表示将第一组值截断为第二组的长度。String2 的长度只有 1 个字符,因此 string1 被截断为该长度。

换句话说: tr -ct '\n' '0' -> tr -t '\000\001\002...01234...ABCDEF...' '0' -> tr '\000' '0 '

试试这个来测试它:

printf '\000afoo\n' | tr -ct '\na' '7'

“任何不是 '\n' 或 'a' 的字符” (-c) 变为 '\000' (-t) 因为为 string2 指定了 '7',它的长度为 1。现在试试这个:

printf '\000afoo\n' | tr -ct '\na' '[7*]'

“任何不是 '\n' 或 'a' 的字符” (-c) 仍然存在,因为 '7' 用于该集中的任何字符。这是 GNU 和历史 BSD tr 的默认行为,因此如果未指定 -t,则 '7' 与 '[7*]' 一样有效。对于 System V 和 POSIX tr,'[7*]' 是一种重复形式,而 '7' 只是将第一组中的第一个字符替换为 '7',这可以说更直观,并且肯定是您的问题所在的一部分from(如果指定了 -t,GNU tr 将行为更改为 System V)。

于 2013-08-24T14:25:48.803 回答