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

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

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

$ echo clayii | sed -e '/clayii/ y/clayk/kieio/'
kieiii

换句话说,如果搜索词 (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

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

答案1

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

[2地址]y/字符串1/字符串2/
             代替全部中字符的出现次数字符串1
             与相应的字符字符串2

操作系统/BSDman页:

[2地址]y/字符串1/字符串2/
             代替全部中字符的出现次数字符串1在图案中
             空格与相应的字符字符串2

GNU sed info页:

是/源字符/目标字符/
             音译任何模式空间中匹配以下任意字符的字符源字符与相应的字符目标字符

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

sed 'y/words/evles/' <<<'words whispered by the drows'

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

但一旦你开始添加模式/需求,事情就会变得复杂。

答案2

珀尔:perl -pe 's{(clayii)}{ ($new=$1) =~ tr/clayk/kieio/; $new }e' file

答案3

它看起来可行 - 你只需要进行某种移入/移出:

echo can ccccc ccccccccclayii sed clay ignore \
     every cclayii thing but the matching word\
     - cclayiicclayii |
sed     -e'y/ /\n/' \
-eh     -e's/\(cclayii\)\1*/ & /g;x;s// /g;s/^/ /' \
-ex     -e's//./;s/\([^ ]* *\)\{2\}/\1 /g;s/^/ /'  \
        -e'y/clayk/kieio/;G;t$' -e:$  \
        -e'/^ \n /{s///;y/ \n/\n /;}' \
-et     -e's/^ *\([^ ]*\) \(.* \n [^ ]*\) /\2\1/;t$'

can ccccc ccccccckkieiii sed clay ignore every kkieiii thing but the matching word - kkieiiikkieiii

……但这并不容易。


然而,正如大多数复杂问题一样,方式如果你使用两个seds 会更容易:

echo can ccccc ccccccccclayii sed clay ignore \
     every cclayii thing but the matching word\
     - cclayiicclayii |
sed -e's/\(cclayii\)\1*/\n&\n /g;G;s/^/ /'|
sed -e'/^ /!y/clayk/kieio/;/./{H;d;}' \
    -e'x;s/\n \{0,1\}//g'

can ccccc ccccccckkieiii sed clay ignore every kkieiii thing but the matching word - kkieiiikkieiii

相关内容