写完这个之后回答,我做了一些谷歌搜索,看看是否可以使 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。
[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
……但这并不容易。
然而,正如大多数复杂问题一样,方式如果你使用两个sed
s 会更容易:
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