Reputation: 65
I'm new to this, just wondering if anyone could help :)
I have a file like this:
start1
12.3
13.2
15.3
end1
How do I find the string end1 and add a few lines before the string, so it looks like:
start1
12.3
13.2
15.3
NaN
NaN
end1
But the number of line added has to depend on a specific number, say 5. If it only has 3 entries between start1 and end1, the numbers of line added is 2.
Upvotes: 1
Views: 1289
Reputation: 204015
It's really not clear whether that number you mention is always something you figure out from the file contents or something you might program but try this:
awk '
/start/ { c=0 }
/end/ { for (i=1; i<c; i++) print "NaN" }
{ print; ++c }
' file
and let us know of any problems.
EDIT: to add c lines if less than 5 lines exist:
awk '
/start/ { c=0 }
/end/ && c<5 { for (i=1; i<c; i++) print "NaN" }
{ print; ++c }
' file
or to pad up to 5 lines:
awk '
/start/ { c=0 }
/end/ { for (i=c; i<=5; i++) print "NaN" }
{ print; ++c }
' file
Upvotes: 1
Reputation: 58483
This might work for you (GNU sed):
sed -r '/^start/!b;n;:a;/\nend/bb;$!{N;ba};:b;/(\n[^\n]*){5}/!s/$/\nNaN/;tb;s/(\nend[^\n]*)(.*)/\2\1/' file
Upvotes: 0
Reputation: 85845
This is better suited to awk
just set c
to the number you require:
$ awk -vc=5 '/start/{n=0}/end/{for(i=0;i++<c+1-n;)print"NaN"}++n' file
start1
12.3
13.2
15.3
NaN
NaN
end1
$ awk -vc=8 '/start/{n=0}/end/{for(i=0;i++<c+1-n;)print"NaN"}++n' file
start1
12.3
13.2
15.3
NaN
NaN
NaN
NaN
NaN
end1
Upvotes: 0
Reputation: 195179
awk -vt=5 '/start1/{print;next;}/end1/{for(x=1;x<=t-i;x++)print "NaN";}++i' file
you just replace the 5 in above one-liner to get different number of "NaN" :)
EDIT: start may not at 1st line.
awk -vt=5 '/start1/{i=0;print;next;}/end1/{for(x=1;x<=t-i;x++)print "NaN";}++i' file
test
kent$ cat t
Empty lines followed
foo
foo1
start1
12.3
13.2
15.3
end1
bar
bar2
kent$ awk -vt=5 '/start1/{i=0;print;next;}/end1/{for(x=1;x<=t-i;x++)print "NaN";}++i' t
Empty lines followed
foo
foo1
start1
12.3
13.2
15.3
NaN
NaN
end1
bar
bar2
Upvotes: 1
Reputation: 42488
You can easily do this with awk(1)
:
awk '/start1/ {start=NR} /end1/ && start {for (i=NR-start;i<=5;++i) {print "NaN"}} 1'
That will record which line the string start1
was on, and when it sees the line the string end1
, it will output up to 5 lines of NaN depending on how far apart start1
and end1
are. Change the 5 to be whatever you need.
Upvotes: 2
Reputation: 14454
I admit that I do not know a straightforward way to do what you want with Sed. Someone will probably post an Awk answer, which is fine, but if one does not mind the run-time cost of starting the Perl interpreter, this works, too:
perl -we 'print until eof() or ($_ = <>) =~ /^start1\s*$/; exit if eof(); print; my $i = 5; --$i, print until eof() or ($_ = <>) =~ /^end1\s*$/; --$i, print "NaN\n" until $i <= 0; print; print <>;'
Upvotes: 0
Reputation: 2002
You can use sed
to do such a thing:
`sed /end1/lineToAdd0\nlineToAdd1\netc\nend1/g < file`
I’m not sure about the \n
, I don’t remember if it’s sed
that interprets it a special way.
Upvotes: 0