views:

3508

answers:

6

Trying to debug an issue with a server and my only log file is a 20GB log file (with no timestamps even! Why do people use System.out.println() as logging? In production?!)

Using grep, I've found an area of the file that I'd like to take a look at, line 347340107.

Other than doing something like

head -<$LINENUM + 10> filename | tail -20

... which would require head to read through the first 347 million lines of the log file, is there a quick and easy command that would dump lines 347340100 - 347340200 (for example) to the console?

update I totally forgot that grep can print the context around a match ... this works well. Thanks!

+8  A: 

with GNU-grep you could just say

grep --context=10 ...
+1  A: 

What about:

tail -n +347340107 filename | head -n 100

I didn't test it, but I think that would work.

itsmatt
+2  A: 

With sed -e '1,N d; M q' you'll print lines N+1 through M. This is probably a bit better then grep -C as it doesn't try to match lines to a pattern.

mweerden
+9  A: 

I found two other solutions if you know the line number but nothing else (no grep possible):

Assuming you need lines 20 to 40,

sed -n '20,40p' file_name

or

awk 'FNR>=20 && FNR<=40' file
Sklivvz
+2  A: 

I'd first split the file into few smaller ones like this

$ split --lines=50000 /path/to/large/file /path/to/output/file/prefix

and then grep on the resulting files.

Luka Marinko
agreed, break that log up and create a cron job to do that properly. use logrotate or something similar to keep them from getting so huge.
Tanj
+3  A: 

Uh, I'm happy you solved the issue, but if you first were sceptical against using head because it's ineffient to read all the uninteresting data before the hit, then ... isn't grep also forced to read that data just the same?

I'm pretty confident it is, there is no magical shortcut it can take to find the hit without reading through the data, looking for it. If you already know in advance where the hit is, just skipping lines (with head) sounds more efficient than trying to match on each line (with grep).

unwind
You're right; there is no short cut.
Jonathan Leffler