Reputation: 12190
I'm trying to insert new object to feLinks
array therefore I'm trying to target closing array tag ];
so I can append an object to the array.
I'm trying to match the first occurrence of ];
so I could inject a new object
I do know about lazy quantifier, but haven't been able to make it work.
var fedLinks = [{
Name:" Test",
data:'value',
tag:"first"
}];
var fedSet = [
{
Name:"Dashboard",
data:fedLinks
}];
Here is what I have tried
];.+?
But it returns no match
Upvotes: 0
Views: 458
Reputation: 203502
Use awk with literal strings for robustness, portability, and clarity (none of which you can have with a sed solution):
awk '
NR==FNR{ add=(NR>1 ? add ORS : "") $0; next }
s=index($0,"];") { $0=substr($0,1,s-1) add substr($0,s); add="" }
1' add.txt test.txt
The above reads the new record as a literal string from the file "add.txt" then inserts that just before the literal string "];" appears in "test.txt" and prints the result, again as a literal string. That way you don't have to worry about escape characters or regexp metacharacters or backreferences or anything else in either input file - everything will be reproduced exactly as you typed it. It will also work as-is with any awk on any UNIX box.
For example (borrowing @Weike's sample added text):
$ cat test.txt
var fedLinks = [{
name: "test1",
data: "value1",
tag: "first"
}];
var fedSet = [
{
name: "Dashboard",
data: fedLinks
}];
.
$ cat add.txt
,{
name: "test2",
data: "value2",
tag: "second"
}
.
$ awk 'NR==FNR{add=(NR>1 ? add ORS : "") $0; next} s=index($0,"];"){$0=substr($0,1,s-1) add substr($0,s); add=""} 1' add.txt test.txt
var fedLinks = [{
name: "test1",
data: "value1",
tag: "first"
},{
name: "test2",
data: "value2",
tag: "second"
}];
var fedSet = [
{
name: "Dashboard",
data: fedLinks
}];
Upvotes: 1
Reputation: 1270
$ sed -nr ':start;/\];/!{p;n;bstart};SUBSTITUTE;:end;p;n;bend'
Explains:
:start;/\];/!{p;n;bstart}
: use a loop to print the line what it is util matching the first line containing \];
.:end;p;n;bend
: use a new loop
to print the lines after the with the first ];
.Here, I'll use s
command to substitute
the null char
between }
& ]
with your new object
:
s/(})(])/\1,{\n name: "test2",\n data: "value2",\n tag: "second"\n}\2/
for example:
$ cat test.txt
var fedLinks = [{
name: "test1",
data: "value1",
tag: "first"
}];
var fedSet = [
{
name: "Dashboard",
data: fedLinks
}];
we want to add another object
to fedLinks
array:
$ sed -nr ':start;/\];/!{p;n;bstart};s/(\})(\])/\1,{\n name: "test2",\n data: "value2",\n tag: "second"\n}\2/;:end;p;n;bend' test.txt
var fedLinks = [{
name: "test1",
data: "value1",
tag: "first"
},{
name: "test2",
data: "value2",
tag: "second"
}];
var fedSet = [
{
name: "Dashboard",
data: fedLinks
}];
We can change the way of thinking how to achieve functional. Instead of finding the first }];
, we can find complete feLinks array block
, then do your insert
operations.
$ sed -r '/fedLinks.*\[\{/!bend;:loop;N;/\}\]/{SUBSTITUTE;bend};bloop;:end'
Explains:
fedLinks.*\[\{
: find the beginning of the array
which you want to insert a new object; or just jump to label end
to read next line from stream.:loop
: set a label loop
to read the remaining
lines which belong to the fedLinks
array.N;...;bloop
: append \n
and next line from stream into pattern space
util matching the \}\]
, which means the end of fedLinks
array./\}\]/{SUBSTITUTE;bend};bloop
: deal with the fedLinks
array when fetching all lines belonged to the fedLinks
array and then jump to label end
.for example:
$ sed -r '/fedLinks.*\[\{/!bend;:loop;N;/\}\]/{s/(})(])/\1,{\n name: "test2",\n data: "value2",\n tag: "second"\n}\2/;bend};bloop;:end' test.txt
var fedLinks = [{
name: "test1",
data: "value1",
tag: "first"
},{
name: "test2",
data: "value2",
tag: "second"
}];
var fedSet = [
{
name: "Dashboard",
data: fedLinks
}];
Upvotes: 1