problem with sed command and csh

Olivier Regnier oregnier at oregnier.net
Mon Jun 18 12:40:10 UTC 2007


Nikos Vassiliadis a écrit :
> On Saturday 16 June 2007 16:35, Olivier Regnier wrote:
>   
>> Olivier Regnier a ιcrit :
>>     
>>> Nikos Vassiliadis a ιcrit :
>>>       
>>>> On Friday 15 June 2007 13:29, Olivier Regnier wrote:
>>>>         
>>>>> Hi everybody,
>>>>>
>>>>> Actually, i'm working on FreeBSD 6.2 and csh shell. With a sh
>>>>> script, i trying to execute this command :
>>>>> sed -e "s/MAKE_ARGS\([^{]*\){/MAKE_ARGS\1{\n\t'mail/nbsmtp' =>
>>>>> 'WITH_IPV6=1 WITH_SSL=1',/" > /usr/local/etc/pkgtools.conf
>>>>>
>>>>> The result is not correct, i have an error :
>>>>> sed: 1: "s/MAKE_ARGS\([^{]*\){/M . . .": bad flag in subsitute
>>>>> command: 'n'
>>>>>
>>>>> Can you help me please ?
>>>>>           
>>>> s/MAKE_ARGS\([^{]*\){/MAKE_ARGS\1{\n\t'mail/nbsmtp' =>
>>>> This n is invalid--------------------------^^^
>>>>
>>>> You should add a backslash before each slash
>>>> that is not used as a separator for the s command.
>>>> E.g.
>>>> s/I want to substitute the \/ character/with the _ character/
>>>> s/\/\/\//three slashes/
>>>>
>>>> You can also use a separator of choice for the s command.
>>>> That is:
>>>> s/foo/bar/ is equivalent to s at foo@bar@
>>>> is equivalent to sAfooAbarA
>>>> is equivalent to s1foo1bar1.
>>>>
>>>> keep in mind, that our sed might not be
>>>> totally compatible with GNU sed.
>>>>
>>>> HTH, Nikos
>>>>         
>>> Thank for you anserw but the result is bad again :)
>>> I tryed this : sed
>>> "s/MAKE_ARGS\([^{]*\){/MAKE_ARGS\1{\n\t'mail\/nbsmtp' => 'WITH_IPV6=1
>>> WITH_SSL=1',/" > /usr/local/etc/pkgtools.conf
>>> but i have this with cat /usr/local/etc/pkgtools.conf
>>>
>>> MAKE_ARGS = {nt'mail/nbsmtp' => 'WITH_IPV6=1 WITH_SSL=1',
>>> }
>>>
>>> Sed and csh is strange no ? I think \n \t not supported by csh.
>>>       
>> well yesterday i tried with awk command :
>> echo MAKE_ARGS = { | awk '{ sub(/MAKE_ARGS = {/, "MAKE_ARGS =
>> {\n\t\'\'ports-mgmtp/portupgrade' =>
>> \'\'WITH_BDB4=1',\n\t\'\'sysutils/fastest_cvsup' =>
>> \'\'WITH_ROUNDTRIP=1',\n\t\'\'mail/nbsmtp' =>'WITH_IPV6=1"
>> "WITH_SSL=1',\n}"); print; }'
>>
>> The resultat is not bad but incomplete :
>>
>> MAKE_ARGS = {
>>        'ports-mgmtp/portupgrade => 'WITH_BDB4=1,
>>        'sysutils/fastest_cvsup => 'WITH_ROUNDTRIP=1,
>>        'mail/nbsmtp => 'WITH_IPV6=1 WITH_SSL=1,
>> }
>>
>>
>> I should have that :
>>
>> MAKE_ARGS = {
>>        'ports-mgmtp/portupgrade*'* => 'WITH_BDB4=1*'*,
>>        'sysutils/fastest_cvsup*'* => 'WITH_ROUNDTRIP=1*'*,
>>        'mail/nbsmtp*'* => 'WITH_IPV6=1 WITH_SSL=1*'*,
>> }
>>
>>     
>
> Single quotes(') have special meaning to the shell. You
> have to cancel the special meaning using backslashes.
> For example:
> %set a = foo\'bar
> %echo $a
> foo'bar
> %set a = foo\"bar
> %echo $a
> foo"bar
>
> As I see in your code above, not every single quote is backslashed.
> Asterisks should be backslashed in order to passed literally to awk.
> awk has also special characters, which also should be backslashed
> to be treated as simple characters. For example(bash, not csh):
> nik:0:~$ echo | awk '{ print("foo\"bar") }'
> foo"bar
>
> It gets complicated since some characters are special to both, csh
> and awk. Frequently, you have to use backslashed backslashes, to get
> the wanted result... You should check the csh and awk manual page.
>
> Last but not least, do you have use csh?
> It's not recommend for scripting.
>
> HTH, Nikos
>   
Hello,

I founded solution with awk command and that works well.

cat /usr/local/etc/pkgtools.conf | awk '{ sub(/^[ \t]*MAKE_ARGS = {/, 
"&\n\t\x27ports-mgmtp/portupgrade\x27 => 
\x27WITH_BDB4=1\x27,\n\t\x27sysutils/fastest_csvsup\x27 => 
\x27WITH_ROUNDTRIP=1\x27,\n\t\x27mail/nbsmtp\x27 => \x27WITH_IPV6=1 
WITH_SSL=1\x27,\n"); print; }' > /usr/local/etc/pkgtools.conf

Thank you :)


More information about the freebsd-questions mailing list