I have database log file which looks like this
tbl
---
tmp1
col1|col2
---------
22| 33
32| 45
tbl
---
tmp2
col1|col2| col3
---------------
22| 33| 123
32| 45| 456
I am trying to write a sed command which find lines which begin with '---' and adds a carriage return two lines above. So that the output looks like:
tbl
---
tmp1
col1|col2
---------
22| 33
32| 45
tbl
---
tmp2
col1|col2| col3
---------------
22| 33| 123
32| 45| 456
Is it possible to do this using sed? If so how?
Reversing the input using tac as suggested by Sundeep makes this problem a whole lot easier:
tac data.txt | sed '/^----*$/ {N;a\
}' | tac | sed '2,$p'
This is a difficult sed-only problem (at least for me). I was close, but opted for perl. sed is turing complete, so this can definitely be translated. Intuitively, I'd say this could be completed with one extra line buffer and I hope someone answers with a sed-only implementation. There were times where it simply didn't hold. There were so many weird cases that I opted for queuing the whole way through:
my @queue = ();
while (<>) {
if (/----*/) {
do {
print $queue[0];
print "\n" if scalar @queue == 2;
shift @queue;
} while (scalar @queue);
print;
} else {
push @queue, $_;
}
}
do print shift @queue while scalar @queue;
I started looking at the problem like:
1
0
2
1
0
The numbers represent offsets from the following ---* line where 0 is the ----* line. When the offset is 2, print a new line.
The problem statement is clearly expressed as:
print \n before previous line if line ~ /----*/.
Anyway, here's the invocation / output:
$ perl script.pl data.txt
tbl
---
tmp1
col1|col2
---------
22| 33
32| 45
tbl
---
tmp2
col1|col2| col3
---------------
22| 33| 123
32| 45| 456
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With