当输入是一行(或者你乐意在每一行的开头从 1 开始计数),并且想要忽略大写的 Rabbit 时,可以使用以下解决方案:
首先用一个字符替换所有兔子sed
可以匹配。
替换第二个兔子角色并恢复其他兔子。
sed -r 's/rabbit/\r/g; s/(\r[^\r]*)\r/\1hare/g; s/\r/rabbit/g' sample.txt
编辑,附加说明:
当输入文件是一个干净的unix风格的文件(没有MS-DOS结尾\r\n)时,我们知道该字符\r
是独特的。后sed -r 's/rabbit/\r/g
每只兔子代表\r
(这封信r
其实第一个字母并不短rabbit
但第一个return
).
现在你想要寻找序列<rabbit><not-a-rabbit><rabbit>
,用我们的新符号表示就是序列\r[^\r]*\r
, where [^\r]*
代表任何不包含兔子字符的字符序列。
当我们找到两只兔子时,我们想记住第一只带有非兔子字符的兔子。在sed
你可以记住一个匹配的序列\(..\)
,或使用选项-r
and (..)
。您可以调用第一个存储位置(我们这里只有一个)\1
,在这种情况下第一只兔子\r
和非兔子角色。第二只兔子\r
被替换为hare
.
更换第二个后\r
(全球上线,所以每隔一秒),我们要改造\r
把兔子放进绳子里rabbit
.
更多的可能性
当您的输入文件超过 1 行时,您可能需要不同的内容。第一行有一只兔子,第二行有一只兔子,你怎么能抓住第二只兔子呢?在执行上述操作之前sed
命令,您需要将输入文件转置为 1 行。之后您想要恢复行结束符,因此您需要用特殊字符替换行结束符。通常我会使用\r
为此,但这个角色是为兔子保留的。人物\v
是可能的,导致
tr '\n' '\v' < sample.txt |
sed -r 's/rabbit/\r/g; s/(\r[^\r]*)\r/\1hare/g; s/\r/rabbit/g' |
tr '\v' '\n'
当您还想替换大写的 Rabbits 时,我们可以将这些 Rabbits 转置为\a
.
您可以要求任何兔子(大或小)[\r\a]
,什么会使命令变得更加复杂:
tr '\n' '\v' < sample.txt |
sed -r 's/rabbit/\r/g; s/Rabbit/\a/g;
s/([\r\a][^\r\a]*)[\r\a]/\1hare/g;
s/\r/rabbit/g; s/\a/Rabbit/g' |
tr '\v' '\n'
当你想替换大写的 Rabbit 时\a
带有大写字母Hare
,命令将变得更加复杂(您需要另一个特殊字符)。
我想使用\x01
用于标记要改变的[兔子。
tr '\n' '\v' < sample.txt |
sed -r 's/rabbit/\r/g;
s/Rabbit/\a/g;
s/([\r\a][^\r\a]*)([\r\a])/\1\x01\2/g;
s/\x01\r/hare/g;
s/\x01\a/Hare/g;
s/\r/rabbit/g; s/\a/Rabbit/g' |
tr '\v' '\n'