0

I'm working in a Zend CRUD generator and I have to replace the word "test" which is in $targetForm file with the form code of each field.

field[0]="foo"
field[1]="bar"

textareafield='$'"acme_en = new Utils_Form_Element_Textarea('acme_en',array('langblock'=>'en', 'isWysiwyg' => true));
    "'$'"this->addElement("'$'"acme_en);
    "'$'"this->addElement('textarea','acme_fr', array( 'label'=>__('acme'), 'langblock'=>'fr', 'isWysiwyg' => true, 'altLangElem' => "'$'"acme_en));"    

for ((i=0; i<${#field[@]}; i++));
do
    formfield[$i]=$textareafield
    formfield[$i]=${formfield[$i]//acme/${field[$i]}}
    echo ${formfield[$i]}
    sed -i "s/test/test\n        ${formfield[$i]}/" $targetForm
done

The command line says:

$foo_en = new Utils_Form_Element_Textarea('foo_en', array('langblock'=>'en', 'isWysiwyg' => true)); $this->addElement($foo_en); $this->addElement('textarea','foo_fr', array( 'label'=>__('foo'), 'langblock'=>'fr', 'isWysiwyg' => true, 'altLangElem' => $foo_en));
sed: -e expression #1, char 120: unterminated `s' command
$bar_en = new Utils_Form_Element_Textarea('bar_en', array('langblock'=>'en', 'isWysiwyg' => true)); $this->addElement($bar_en); $this->addElement('textarea','bar_fr', array( 'label'=>__('bar'), 'langblock'=>'fr', 'isWysiwyg' => true, 'altLangElem' => $bar_en));
sed: -e expression #1, char 120: unterminated `s' command

Maybe there's a problem with the specials character but I don't know how to solve it.

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
Sadiel
  • 1,344
  • 3
  • 18
  • 33

2 Answers2

2

This error you get very likely has nothing to do with using \n in sed substitution (especially since you mentioned in the comments that you are using GNU sed version 4.2.1).


The real culprit is textareafield which contains a multi-line string.

What happens is that when ${formfield[$i]} gets expanded, your sed command looks like this

sed -i "s/test/test\n        line1
line2
line3/"

This is problematic because without terminating lines with a literal \, sed would interpret each line as a complete command in itself, in this case

s/test/test\n        line1

which is missing a / at the end, hence the error "unterminated `s' command".

To fix this, what we want is to insert a \ to the end of every line except the last, i.e.

sed -i "s/test/test\n        line1\
line2\
line3/"

I got your example to work by adding two lines

for ((i=0; i<${#field[@]}; i++));
do
    formfield[$i]=$textareafield
    formfield[$i]=${formfield[$i]//acme/${field[$i]}}
    formfield[$i]=${formfield[$i]//\;/\;\\}
    formfield[$i]=${formfield[$i]%\\}
    echo ${formfield[$i]}
    sed -i "s/test/test\n        ${formfield[$i]}/" $targetForm
done

Since all the lines in textareafield end in ;, I replaced all ; with ;\, then removed the last \ from the last line.

doubleDown
  • 8,048
  • 1
  • 32
  • 48
1

sed does not support \n in the substitution, but you can use a literal newline if you escape it. Also, you need to quote the ' characters. Here is one way of doing it:

for ((i=0; i<${#field[@]}; i++));
do
    formfield[$i]=$textareafield
    formfield[$i]=${formfield[$i]//acme/${field[$i]}}
    sedexpr="${formfield[$i]}"
    sedexpr="${sedexpr//\'/\'}"
    sedexpr="${sedexpr//
/\\
}"
    sed -i "s/test/test\
        ${sedexpr}/" $targetForm
done

But at this level of complexity you're probably better off switching to something like Python.

Community
  • 1
  • 1
andrewdotn
  • 32,721
  • 10
  • 101
  • 130
  • It doesn't works but anyway, in other part of my code it works: `sed -i "s//\n ${line[$i]}/" $targetViewForm` – Sadiel Nov 12 '12 at 22:36
  • Which version of sed are you running, and on which operating system? – andrewdotn Nov 12 '12 at 22:39
  • GNU sed version 4.2.1; Ubuntu 12.04.1 LTS – Sadiel Nov 12 '12 at 22:43
  • with `textareafield="acme-test"` it works, that's why I think the problem is with the ' character. – Sadiel Nov 12 '12 at 22:45
  • It works if I delete the new line in the variable `textareafield='$'"acme_en = new Utils_Form_Element_Textarea('acme_en', array('langblock'=>'en', 'isWysiwyg' => true)); "'$'"this->addElement('textarea','acme_fr', array( 'label'=>__('acme'), 'langblock'=>'fr', 'isWysiwyg' => true, 'altLangElem' => "'$'"acme_en));"` And with \n in the Sed line Thanks! – Sadiel Nov 12 '12 at 23:02
  • Turns out you need to quote both `'` and newlines. See the revised version. – andrewdotn Nov 12 '12 at 23:13