I want to globally substitute all \n new line characters with their \n escape sequence and all ' single quote characters with two '' of them like so:

function esc_foobar {
    # Escapes any "'" single quotation character.
    local -r esc_quot="s:':'':g"
    # Escapes any "\n" new line character.
    local -r esc_nl=':a;N;$!ba;s:\n:\\n:g'
    # Escape everything in one sed run.
    sed -- "$esc_quot;$esc_nl" foobar.txt

Given that the foobar.txt file contains:

Foo's bar
Bar's foo

Only the first ' single quote character gets doubled.

Reversing the order of the esc_quot and esc_nl substitutions in the sed command to $esc_nl;$esc_quot works, i.e. all ' single quote characters get doubled as expected.

Why is this so?

  • I know to substitute with sed globally you should use s'/foo/bar/g' The s means substitute and g means globally – user251046 Aug 2 '14 at 11:37
  • 3
    I don't know for sure, but I suspect that what is happening is that in the first form, the first line is scanned, the quote mark replaced, then the line is rescanned, and the newline character is replaced. The second line is no longer there to be scanned, because it is now already joined to the first. In the second form, the first line is scanned, and the new line character is replaced, the line now containing both the first and second line is rescanned and all quotes replaced. Perhaps someone can confirm or correct my understanding? – Warwick Aug 2 '14 at 11:53
  • @Warwick: Sounds reasonable. – Tim Friske Aug 2 '14 at 12:32

After working myself into Sed and particularly trying to get my head around Sed's N command I came up with the following little Sed script that works for me:

sed -- '$!N;s:\n:\\n:g;'"s:':'':g"

The second variant of the Sed script from my question has the problem that it leaves the last line untouched if the number of lines of input happens to be odd.

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.