我对tr
选项的执行顺序感到困惑。
例如,有一个这样的命令:
echo 123 | tr -ct '\n' '0'
这是如何执行的?是-c
首先执行还是-t
?
我也对这个命令的结果感到困惑。
我认为-c
首先执行,结果为123
,然后-t
将被执行,结果为023
,最终为023\n
。但这是错的,正确答案是123\n
,
我不知道为什么,有人能告诉我吗?
答案 0 :(得分: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
答案 1 :(得分: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。)