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

  • no, sed would works on line by line. Chnege your sed command to, sed -i '0,s#</verse-sub-section>#</section>#' file – Avinash Raj Feb 11 '15 at 2:53
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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.