bash-当字符串由未知长度组成但同一字符时,多字符串更换
假设一个多行文本字符串,其中某些行以键字符开始(在我们的情况下为“#”)。进一步假设您希望用不同的字符替换目标字符的所有实例(在我们的情况下)更多相邻的副本(例如“ ooo”)。此替换应以所有不从密钥字符开始的行中进行,并且必须对病例敏感。
例如,以下几行...
#Foo bar
Foo bar
#Baz foo
Baz foo
应该转换为:
#Foo bar
FOO bar
#Baz foo
Baz fOO
以下尝试使用sed
不会保留正确数量的目标字符数:
$ echo -e "#Foo bar\nFoo bar\n#Baz foo\nBaz foo" | sed '/^#/!s/o\{2,\}/O/g'
#Foo bar
FO bar
#Baz foo
Baz fO
什么代码(使用sed
或其他)可以正确进行所需的替换?
Assume a multi-line text string in which some lines start with a key-character ("#" in our case). Further assume that you wish to replace all instances of a target character ("o" in our case) with a different character ("O" in our case), if - and only if - that target character occurs as a string of two or more adjacent copies (e.g., "ooo"). This replacement is to be done in all lines that do not start with the key-character and must be case-sensitive.
For example, the following lines ...
#Foo bar
Foo bar
#Baz foo
Baz foo
are supposed to be converted into:
#Foo bar
FOO bar
#Baz foo
Baz fOO
The following attempt using sed
does not retain the correct number of target characters:
$ echo -e "#Foo bar\nFoo bar\n#Baz foo\nBaz foo" | sed '/^#/!s/o\{2,\}/O/g'
#Foo bar
FO bar
#Baz foo
Baz fO
What code (with sed
or otherwise) would conduct the desired replacement correctly?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
使用 sed
Using
sed
这可能对您有用 (GNU sed):
总而言之,使用指定的一个或多个字符(在本例中为
O
)来替换起始位置的两个或多个o
一行不是#
。用指定的字符填充保留空间。
如果该行以
#
开头,则换行。如果该行不包含两个或
o
,则换行。否则,用换行符将两个或多个 o 括起来。
附加替换字符,然后用指定字符替换两个换行符之间的非换行符。
当当前
o
组的所有替换项均已替换后,请按上述方式继续检查更多内容。找到所有替换后,打印修改后的行。
允许多次替换的解决方案:
This might work for you (GNU sed):
In overview, use a designated character or characters (in this case
O
) to replace two or moreo
's where the start of a line is not#
.Prime the hold space with the designated character.
If the line starts with
#
, break out.If the line does not contain two or
o
's, break out.Otherwise, surround the two or more
o
's by newlines.Append the replacement character and then replace non-newline characters between two newlines with the designated character.
When all replacements for the current set of
o
's have been replaced, check for more by continuing as above.Once all replacements have been found, print the amended line.
A solution allowing for multiple replacements:
您可以使用 Perl:
这里,
^#.*(*SKIP)(*F)
匹配并跳过以#
开头的所有行,然后是o{2, }
匹配两个或多个o
字符,"O" x length($&)
将这些匹配替换为O
重复匹配大小的次数($&
是匹配值)。请注意g
后面的e
标志,用于计算右侧的字符串。请参阅在线演示:
输出:
You can use Perl:
Here,
^#.*(*SKIP)(*F)
matches and skips all lines starting with#
, theno{2,}
matches two or moreo
chars, and"O" x length($&)
replaces these matches withO
that is repeated the match size times ($&
is the match value). Note thee
flag afterg
that is used to evaluate the string on the right-hand side.See the online demo:
Output: