在Android中使用“sed”而不使用“g”修饰符?

在Android中使用“sed”而不使用“g”修饰符?

我在已 root 的 Nexus 10 中安装了 Stericson busy box。

我想将文件中的第一个实例替换</verse-sub-section></section>

          <section>Psalm of David</verse-sub-section>
          <verse-sub-section>David Weeps</verse-sub-section>

sed -i 's#</verse-sub-section>#</section>#' file即使我最后不使用修饰符,也会将所有内容替换</verse-sub-section>为。</section>g

这是由于 busybox 造成的吗?还是我的命令错误?我应该用什么来实现这个(在带有busybox的anroid中)?

Busybox版本:1.23.1

答案1

为了将替换限制为文件的一部分,直到并包括第一个匹配实例,您可以在替换命令前面添加范围的形式1,\#pattern#

busybox sed '1,\#</verse-sub-section># s#</verse-sub-section>#</section>#' file

请注意在备用分隔符之前使用反斜杠转义符,\#除非命令引入反斜杠转义符s

请注意,如果第一行出现匹配,则不会产生所需的行为; GNU sed 支持一系列形式0,\#pattern#来处理这种情况,但 busybox sed - 至少我能够测试的版本BusyBox v1.22.1 (Ubuntu 1:1.22.0-8ubuntu1)- 似乎不支持。

答案2

你的问题含糊不清。如果你想找到最先的实例</verse-sub-section> 在整个文件中,并将其替换为</section>,然后查看其他答案。我的解释是,鉴于输入

1    <section>Genesis</verse-sub-section>
2    <verse-sub-section>In the beginning, God ...</verse-sub-section>
3    <section>Psalm of David</verse-sub-section>
4    <verse-sub-section>David Weeps</verse-sub-section>

你想</verse-sub-section></section>第 1 行和第 3 行替换。如果这是你的问题,答案是

sed -i 's#\(<section>.*\)</verse-sub-section>#\1</section>#' file

放入<section>老的命令的字段保证只处理包含的行。定界了该行的一部分:从 开始 并一直到(但不包括) 的部分。而在s/old/new/<section>\(…\)<section></verse-sub-section>\1新的字段导致匹配字符串的已识别子字符串被插入回文件中——即保持不变。

至少在普通版本的 *nix 中它是这样工作的。 Android 应该没有什么不同,但我不能保证它能在 busybox 中工作。

相关内容