Reputation: 7569
I have file1.txt in UNIX as following
[Section A]
$param1=value1
$param2=value2
[Section B]
$param1=value1
$param2=value2
$param3=value3
I want to edit value2 in Section B to be new_value2 programmatically
[Section A]
$param1=value1
$param2=value2
[Section B]
$param1=value1
$param2=new_value2
$param3=value3
Any idea what should be the unix command to do this (using sed?)?
Thanks a lot.
Upvotes: 2
Views: 1721
Reputation: 7640
Really simple solution.
ex file1.txt <<"INPUT"
/Section B
/param2
s/value2/new_value2/
:x
INPUT
Upvotes: 0
Reputation: 50124
sed -ie '/^\[Section B\]$/,/^$/s/^\$param2=value2$/$param2=new_value/' foo.txt
Edit: The above example is very strict regarding the old value and space characters. I add another example which is probably more suitable. The sed script consists of one command and is prefixed by the following address range:
/^\[Section B\]/,/^\[.*\]/
The address range consists of two regular expressions separated by a comma, and restricts the following command to the lines starting from where the first address matches, and continues until the second address matches (inclusively).
s/^\(\$param2[ \t]*=[ \t]*\).*$/\1new_value/
The substitution command does the actual replacement with the range. Everything together:
sed -ie '/^\[Section B\]/,/^\[.*\]/s/^\(\$param2[ \t]*=[ \t]*\).*$/\1new_value/' foo.txt
Upvotes: 3
Reputation: 58637
TXR program which parses file, performs edit, and reconstitutes:
@;
@; grab four comand line arguments
@;
@(next :args)
@(cases)
@file
@new_section
@new_param
@new_value
@(or)
@(throw "arguments needed: file section param value")
@(end)
@;
@; hash table mapping sections to assocation lists of values
@;
@(bind sec @(hash :equal-based))
@;
@; parse file, obtaining list of section names and filling in
@; section hash with an associ list of entries.
@;
@(next file)
@(collect)
[Section @secname]
@ (collect)
$@param=@val
@ (until)
@ (end)
@(do (set [sec secname] [mapcar cons param val]))
@(end)
@;
@; now edit
@;
@(do (let ((sec-entries [sec new_section]))
(if (null sec-entries)
(push new_section secname))
(set [sec new_section] (acons-new new_param new_value sec-entries))))
@;
@; now regurgitate file
@;
@(do (each* ((s secname)
(ent (mapcar (op sec) s)))
(format t "[Section ~a]\n" s)
(each ((e ent))
(format t "$~a=~a\n" (car e) (cdr e)))
(put-string "\n")))
Test runs:
# edit section B param2 to new_value2
$ txr config.txr config.txt B param2 new_value2
[Section A]
$param1=value1
$param2=value2
[Section B]
$param1=value1
$param2=new_value2
$param3=value3
# add new parameter x with value y to section A
$ txr config.txr config.txt A x y
[Section A]
$x=y
$param1=value1
$param2=value2
[Section B]
$param1=value1
$param2=value2
$param3=value3
# add new section with new parameter
$ txr config.txr config.txt foo bar xyzzy
[Section foo]
$bar=xyzzy
[Section A]
$param1=value1
$param2=value2
[Section B]
$param1=value1
$param2=value2
$param3=value3
Exercise for reader: implement deletion of a param/value pair.
Upvotes: 0
Reputation: 67301
In case you needa solution in awk :
nawk -F= '{if($0~/Section B/){print;getline;print;getline;gsub(/value2/,"value9",$2);print}else print}' file3
tested Below:
pearl.274> cat file3
[section A]
$param1=value1
$param2=value2
[Section B]
$param1=value1
$param2=value2
$param3=value3
pearl.275> nawk -F= '{if($0~/Section B/){print;getline;print;getline;gsub(/value2/,"new_value2",$2);print}else print}' file3
[section A]
$param1=value1
$param2=value2
[Section B]
$param1=value1
$param2 new_value2
$param3=value3
pearl.276>
Upvotes: -1