sed `y` 命令可以只应用于匹配的文本(而不是整行)

cas*_*cas 4 sed text-processing

写完这个答案后,我进行了一些谷歌搜索,以确定是否可以将 sedy//命令仅应用于匹配而不是整行。我找不到任何相关的东西。

$ echo clayii | sed -e '/clayii/ y/clayk/kieio/'
kieiii
Run Code Online (Sandbox Code Playgroud)

换句话说,如果搜索词 (clayii) 只是输入行中的许多词之一,我希望该y//命令应用于该词而不是该行的其余部分。

即我不想要这个:

$ echo can sed ignore everything but the matching word - clayii | 
    sed -e '/clayii/ y/clayk/kieio/'
ken sed ignore everithing but the metkhing word - kieiii
Run Code Online (Sandbox Code Playgroud)

这可能sed吗?或者我需要使用更强大的东西perl吗?

don*_*sti 7

不,该y命令适用于模式空间中的所有匹配字符。根据 POSIXsed文档(强调我的):

[ 2addr ]y/ string1 / string2 /
             将string1 中所有出现的字符替换
             为string2 中的相应字符。

OSX/BSDman页面:

[2addr]y/ string1 / string2 /
             替换模式中string1所有出现的字符
             空格与string2 中的相应字符。

GNU sed info页面:

y/源字符/目标字符/
             音译模式空间中匹配任何一个的任何字符具有dest-chars 中相应字符
             的source -chars

当然,您可以使用保持缓冲区来保存当前模式空间,然后仅保留匹配项,音译和恢复模式空间,用结果替换初始匹配项,例如比较

sed 'y/words/evles/' <<<'words whispered by the drows'
Run Code Online (Sandbox Code Playgroud)

sed 'h;s/.*\(drows\).*/\1/;y/words/evles/;G;s/\(.*\)\n\(.*\)drows\(.*\)/\2\1\3/' <<<'words whispered by the drows'
Run Code Online (Sandbox Code Playgroud)

但是一旦您开始添加模式/需求,它就会变得复杂。