2

I have Stericson busy box installed in my rooted Nexus 10.

I wanted to replace the first instance of </verse-sub-section> with </section> in the file here:

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

sed -i 's#</verse-sub-section>#</section>#' file replaces all </verse-sub-section> with </section> even when I do not use the g modifier at the end.

Is this due to busybox? Or is my command wrong? What should I use to achieve this (in anroid with busybox)?

Busybox version:1.23.1

1
  • no, sed would works on line by line. Chnege your sed command to, sed -i '0,s#</verse-sub-section>#</section>#' file Commented Feb 11, 2015 at 2:53

2 Answers 2

1

In order to limit the replacement to a portion of the file up to and including the first matching instance, you can prepend the substitute command with a range of the form 1,\#pattern# i.e.

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

Note the use of the backslash escape before the alternate delimiter \# except where it is introduced by the s command.

Note that this will not have the desired behaviour if a match occurs in the first line; GNU sed supports a range of the form 0,\#pattern# to handle this situation, but busybox sed - at least the version I am able to test, BusyBox v1.22.1 (Ubuntu 1:1.22.0-8ubuntu1) - does not appear to.

1

Your question is ambiguous.  If you want to find the very first instance of </verse-sub-section> in the entire file, and replace it with </section>, then see the other answer(s).  My interpretation is that, given the input

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>

you want to replace </verse-sub-section> with </section> on lines 1 and 3.  If that's your question, the answer is

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

Putting <section> in the old field of the s/old/new/ command guarantees that only lines containing <section> will be processed.  The \(…\) delimits a part of the line: the part starting with <section> and going up to (but not including) the </verse-sub-section>.  And the \1 in the new field causes the identified substring of the matched string to be inserted back into the file -- i.e., left untouched.

At least that's how it works in normal versions of *nix.  Android shouldn't be any different, but I can't guarantee that it will work in busybox.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.