tar (and cpio and afio and pax and similar programs) are stream-oriented formats - they are intended to be streamed direct to a tape or piped into another process. while, in theory, it would be possible to add an index at the end of the file/stream, i don't know of any version that does (it would be a useful enhancement though)
it won't help with your existing tar or cpio archives, but there is another tool, dar ("disk archive"), that does create archive files that contain such an index and can give you fast direct access to individual files within the archive.
if dar isn't included with your unix/linux-dist, you can find it at:
http://dar.linux.free.fr/
sed -n '10000000,10000020p' filename
You might be able to speed that up a little like this:
sed -n '10000000,10000020p; 10000021q' filename
In those commands, the option -n
causes sed
to "suppress automatic printing of pattern space". The p
command "print[s] the current pattern space" and the q
command "Immediately quit[s] the sed script without processing any more input..." The quotes are from the sed
man
page.
By the way, your command
tail -n 10000000 filename | head 10
starts at the ten millionth line from the end of the file, while your "middle" command would seem to start at the ten millionth from the beginning which would be equivalent to:
head -n 10000010 filename | tail 10
The problem is that for unsorted files with variable length lines any process is going to have to go through the file counting newlines. There's no way to shortcut that.
If, however, the file is sorted (a log file with timestamps, for example) or has fixed length lines, then you can seek into the file based on a byte position. In the log file example, you could do a binary search for a range of times as my Python script here* does. In the case of the fixed record length file, it's really easy. You just seek linelength * linecount
characters into the file.
* I keep meaning to post yet another update to that script. Maybe I'll get around to it one of these days.
Best Answer
I believe something like this would work in busybox:
I don't have the same environment as you, but if you encounter issues with spaces in filenames something like this would work too:
Edit 1:
@stew is right in his post below, du shows the disk usage and not the exact filesize. To change the behavior busybox uses the -a flag, so try:
du -a "$file"
for exact filesize and compare the output/behavior.