3

I have a concatenated log file with multiple logs inside that I'm trying to parse out into individual log files. I will later rename them to the date/time of each. Each log is separated by "--- LOG REPORT ---".

So far I have:

sed -n '/--- LOG REPORT ---/,/--- LOG REPORT ---/p' logname.log > test.out

However, as you can imagine, that only outputs the first instance of the pattern. I looked over the man page for sed and I'm not convinced it can output multiple files. Perhaps I could keep extracting from a file until it's empty but that seems like too much work. How I can achieve this? Maybe I should be using awk instead?

Example of input file filename.log

--- LOG REPORT ---
Mary
Had
A
Little
Lamb
--- LOG REPORT ---
Her
Fleece
Was
White
As
Snow

Desired output:

In filename_1.log

--- LOG REPORT ---
Mary
Had
A
Little
Lamb

In filename_2.log

--- LOG REPORT ---
Her
Fleece
Was
White
As
Snow
0

3 Answers 3

9

How about this command?

csplit logname.log /---\ LOG\ REPORT\ ---/ {*}

Testing

cat logname.log
--- LOG REPORT ---
Mary
Had
A
Little
Lamb
--- LOG REPORT ---
Her
Fleece
Was
White
As
Snow

After running the above command, the output I get is,

cat xx01
--- LOG REPORT ---
Mary
Had
A
Little
Lamb
cat xx02
--- LOG REPORT ---
Her
Fleece
Was
White
As
Snow
6

How about something like

awk '/--- LOG REPORT ---/ {n++;next} {print > "test"n".out"}' logname.log
2
  • Oh wow, that's brilliant. So 'next' is what would select the whole log data until the next occurrence, or end of file, and then n increments the filename. Nice. Commented Aug 20, 2014 at 14:17
  • 2
    The next just prevents the --- LOG REPORT --- record separator line from getting included in the output file(s). You can remove it if you want to include that - I just guessed that is redundant. Commented Aug 20, 2014 at 14:32
2

Wrong tool, use either perl or awk e.g.

cat > splitFileByLogReport.pl <<EOF
#!/usr/bin/perl

undef $/;
$_ = <>;
$n = 0;

for $match (split(/(?=--- LOG REPORT ---)/)) {
      open(O, ">$ARGV[$argnum]" . ++$n);
      print O $match;
      close(O);
}

EOF

Then to run:

perl splitFileByLogReport.pl yourFile.txt
1
  • There's definitely more than one way to skin a cat. I think I'm going to stick with awk for now though. Commented Aug 20, 2014 at 14:18

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.