Reputation: 1434
I have the following very long file:
...
close unit 1
...
...
close unit 1
...
...
close unit 1
stop
I want to insert multiples lines before the last close unit 1
which is before stop
. The file contains an undefined number of close unit 1
.
I found a lot of other similar questions here and there, but the answers couldn't help me... For example I tried https://stackoverflow.com/a/8635732/1689664 but this didn't work...
Upvotes: 2
Views: 1192
Reputation: 58410
This might work for you (GNU sed):
sed '/close unit 1/,$!b;/close unit 1/{x;/./p;x;h;d};H;$!d;x;i\line 1\nline 2\n...' file
Print every line before the first occurrence of close unit 1
as normal. Store collections of lines beginning with close unit 1
in the hold space and print the previous collection before storing the next. At the end of the file, the last collection will still be in the hold space, so insert the lines required and then print the last collection.
Upvotes: 0
Reputation: 123498
Using sed
and tac
:
$ tac inputfile | sed '/close unit 1/ {s/\(.*\)/\1\nLine3\nLine2\nLine1/; :loop; n; b loop}' | tac
...
close unit 1
...
...
close unit 1
...
...
Line1
Line2
Line3
close unit 1
stop
Note that you'd need to specify the input lines in the reverse order in the sed
expression.
Upvotes: 2
Reputation: 241858
Perl solution:
perl -ne ' push @arr, $_;
print shift @arr if @arr > 3;
if ("stop\n" eq $_ and "close unit 1\n" eq $arr[0]) {
print "\n\n"; # Inserted lines
}
}{ print @arr ' long-file > new-file
It keeps a sliding window of last 3 lines, if the last line in the window is stop
and the first one is close unit 1
, it prints the lines.
Another possibility is to use nl
to number the lines, then grep
lines containing close unit 1
, getting the number of the last such a line and using it in a sed
address:
nl -ba long-file \
| grep -F 'close unit 1' \
| tail -n1 \
| ( read line junk
sed -e $line's/^/\n\n/' long-file > new-file
)
Upvotes: 1