tr命令的'-s','-t'和'-c'选项在Unix中如何工作?


12

我很困惑关于方式-s-t以及-c选择在工作TR命令。当我做

echo I am a good boy | tr good bad

我得到的输出:

I am a bddd bdy

这是可以理解的,因为o在中重复了good。代替的最后可能的变化od,因此是输出。

现在当我做

echo I am a good boy | tr -s good bad

输出是

I am a bd bdy

-s选项应该将组1中每个字符的每次重复出现都压缩为单个出现,然后将组1中的每个字符更改为组2中位于相同位置的相应字符。

所以应该是

I am a bad bay.

为什么要改变?

而且,当我做

echo I am a good boy | tr -c good bad

我懂了 dddddddgoodddodd

参考此示例,该-c选项如何工作tr

最后:如何将自己从一个好男孩变成一个坏男孩.... :):P

echo I am a good boy | tr <something>给我的输出为:I am a bad boy

Answers:


12

-s 开关:挤压(删除重复的字符)

echo i am a good boy | tr -s good bad

输出: i am a bd bdy

幕后发生了两件事,使之成为现实。首先,如果to的第二个参数tr短于第一个参数,则重复第二个arg中的最后一个字符,使其长度与第一个相同。因此,等效命令为:

echo i am a good boy | tr -s good badd

发生的另一件事是,当重复第一个参数中的字符时,它们将覆盖以前的任何出现(我指的是中的两个oos good)。现在,该命令等效于:

echo i am a good boy | tr -s god bdd

(第二od更换覆盖以前的oa置换,使其成为冗余)

没有-s开关,输出将是

i am a bddd bdy

使用-s开关tr“压缩” 最后一个参数中列出的所有重复字符,从而保留最终输出:

i am a bd bdy

-c 开关:补码

-c开关用于匹配第一个参数的补码(即,参数1中未列出的所有字符)。结果,arg 1将包含许多字母(256-3)。现在,arg 2发生的情况与前面的情况相同:Arg 2的最后一个字符被重复以匹配长度或Arg1。因此,原始语句为:

echo i am a good boy | tr -c good bad

等效于:

echo i am a good boy | tr abcefhijklmnp... baddddddddddd...

(请注意缺少的字符go并且d在第一个d字符集中,还要注意,它将替换第二个字符集中的所有其他字符-包括空格字符)

这就是为什么i am a good boy变成dddddddgoodddodd

此处提供更多信息:http : //www.linuxjournal.com/article/2563


通常是正确的,除了-s开关会导致tr最后一个参数到tr输入中重复的(不是您所说的第一个)挤压任何字符。在您链接的文章中对此进行了说明,并且在手册页的“描述”部分的最后一段中对此进行了说明。
ravron

4

您的理解-s是不正确的,它用单个字符替换了输入1中重复出现的字符。它不会修改集合,例如。

echo i am a good boy | tr -s god bad

i am a bad bay

-c选项用其补码(即,集合1中未包含的所有字符的集合)替换集合1。例如,您可以使用此命令删除除指定字符以外的所有字符。

echo i am a good boy | tr -cd gobdy

输出

goodboy

:我对-s选项有意思,但是我的问题是,如何:呼应我是个好男孩| tr -s good bad给出的输出为:我是bd bdy,只有在发生这种情况时才有可能:首先将我是一个好男孩,改成我是bddd bdy,然后-s选项将多个d的出现更改为单个即:我是bddd bdy,然后更改为我是bd bdy,这实际上是怎么回事?请为我分解一下,与-c选项相同我是个好男孩,回声如何?tr -cd gobdy给出了这个:好孩子

1

其他答案覆盖tr-s-t-c选项,但出于完整性:

您遇到了麻烦,因为您选择了错误的工具。

  • tr 用于字符转换
  • sed 用于流编辑。

由于goodbad都是流中的字符序列,因此sed是更好的匹配。

echo I am a good boy | <something> 给我的输出为: I am a bad boy

$ echo I am a good boy | sed s/good/bad/g
I am a bad boy

s/..../..../是替补。与第一个正则表达式匹配的任何内容都将被第二个正则表达式替换。/g末尾的标志用于全局替换,这样所有出现的对象将被替换而不仅仅是第一个。

$ echo I am a good boy and a good boy is me. | sed s/good/bad/
I am a bad boy and a good boy is me.

$ echo I am a good boy and a good boy is me. | sed s/good/bad/g
I am a bad boy and a bad boy is me.

0

是。究竟!

tr -s 用单个字符替换重复字符的实例。

(通过手册页。)

因此,它是这样的:

它转换goodbddd。重复的实例是3'd'。

因此,它将三个实例替换为一个实例。

这就是它使BD。:)


2
我们并不期望每个答案都是完美的,但是具有正确拼写,标点和语法的答案更容易阅读。
Ashildr
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.