我想我找到了一些 GNU 解决方案,但我需要 BSDsed
解决方案。
我想做的是一次性替换整个单词。如果这个词是“clayii”,而我的代码是sed 's/c/k/g;s/l/i/g;s/a/e/g;s/y/i/g;s/k/o/g'
,我希望它确实产生“kieii”,但出于明显的原因它会产生“oieiii”。在最后一部分,它会k
在开头搜索并找到它,但如果它搜索整个单词,它永远不会这样做。
显然,“clayii”始终会有所不同,我希望它替换单个字母,但不要从头开始,如果它已经替换了第一个字母n
,然后在开头找到它,则不应重新开始。因此,如果可以检测到的话,基本上忽略已经被替换的内容。
有解决办法吗?
答案1
也许使用y//
(sed 的内置 tr 命令)代替s///
:
$ echo clayii | sed -e '/clayii/ y/clayk/kieio/'
kieiii
请注意,该y//
命令仍然适用于整行,而不仅仅是匹配的单词。
答案2
使用 BSD sed,您可以使用:
sed "s/[[:<:]]clayii[[:>:]]/kieii/g" /path/to/file
答案3
你可以循环它:
echo here is a pat and a tern and a pattern |
sed -e'1{H;x;s/\(.\).*/\1pattern\1replace/;x;}' \
-eG -e'/\(.*\)\(.*\n\)\(\n\1\)\n/!{P;d;}' \
-e's//\3\2/;t-' \
-e:- -e's/\(\n\)\(.\)\(.*\n\)\(.\)/\4\1\3/;t-' \
-e's/\n//;P;d'
here is a pat and a tern and a replace
这会从左到右逐个字符地替换字符。对于每次替换,它将第一个分隔符移动到被替换字符的右侧。如果您l
在循环t
ested 替换之前粘贴 ook 命令,您就会明白我的意思-e:-
:
here is a pat and a tern and a \npattern\nreplace$
here is a pat and a tern and a r\nattern\neplace$
here is a pat and a tern and a re\nttern\nplace$
here is a pat and a tern and a rep\ntern\nlace$
here is a pat and a tern and a repl\nern\nace$
here is a pat and a tern and a repla\nrn\nce$
here is a pat and a tern and a replac\nn\ne$
here is a pat and a tern and a replace\n\n$
here is a pat and a tern and a replace
如果您确实正在寻找某种翻译工作,您也可以这样做。我之前写这个是为了回答另一个问题:
它看起来可行 - 你只需要进行某种移入/移出:
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
对于 BSD,sed
您需要使用文字换行符来代替右侧第一个替换中的转义n
符。\n
sed