# Newbie question: how to seek in a file

**URL:** <https://www.ruby-forum.com/t/newbie-question-how-to-seek-in-a-file/111739>\
**Category:** Ruby\
**Created:** [August 10, 2007, 10:43am UTC](https://www.ruby-forum.com/t/newbie-question-how-to-seek-in-a-file/111739 "2007-08-10T10:43:15Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![ak756](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/b5a626/32.png) [@ak756](https://www.ruby-forum.com/u/ak756)\
**Post date:** [August 10, 2007, 10:43am UTC](https://www.ruby-forum.com/t/newbie-question-how-to-seek-in-a-file/111739/1 "2007-08-10T10:43:15Z")

</div>

Hi

I want to find a string in a text file, then read some bytes data after  
the position of this string. Would anybody kindly help to tell me how to  
do?

Thanks in advance.

---

<div class="post-metadata">

**Author:** ![ak756](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/b5a626/32.png) [@ak756](https://www.ruby-forum.com/u/ak756)\
**Post date:** [August 10, 2007, 11:06am UTC](https://www.ruby-forum.com/t/newbie-question-how-to-seek-in-a-file/111739/2 "2007-08-10T11:06:55Z")

</div>

Hi,

Ak 756 wrote:

> I want to find a string in a text file, then read some bytes data after  
> the position of this string. Would anybody kindly help to tell me how to  
> do?

You could do something like this:

File.open(“my-file.txt”) do |f|  
i = f.read.index(/search/)  
f.seek(i)  
puts f.read(10)  
end

Lutz

---

<div class="post-metadata">

**Author:** ![ak756](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/b5a626/32.png) [@ak756](https://www.ruby-forum.com/u/ak756)\
**Post date:** [August 10, 2007, 11:15am UTC](https://www.ruby-forum.com/t/newbie-question-how-to-seek-in-a-file/111739/3 "2007-08-10T11:15:00Z")

</div>

On Friday 10 August 2007 02:06:53 am Lutz H. wrote:

> i = f.read.index(/search/)  
> f.seek(i)  
> puts f.read(10)  
> end

At that point though, you’ve already read the entire contents of the  
file  
into memory (f.read()) so there’s no point going back and seeking in the  
file when:

- Seeking from memory should always be faster than from disk
- You’re already ignoring the memory issues for large files

---

<div class="post-metadata">

**Author:** ![ak756](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/b5a626/32.png) [@ak756](https://www.ruby-forum.com/u/ak756)\
**Post date:** [August 10, 2007, 11:22am UTC](https://www.ruby-forum.com/t/newbie-question-how-to-seek-in-a-file/111739/4 "2007-08-10T11:22:00Z")

</div>

On Friday 10 August 2007 02:09:56 am Konrad M. wrote:

> my\_data = $1  
> Better yet:  
> READ\_BYTES = 16  
> content = File.open(‘foo’){|f| f.read }  
> my\_data = content[content.index(“find this string”), READ\_BYTES]

# I tried to combine Lutz’s and my earlier ideas

Though this of course assumes the string is found.

---

<div class="post-metadata">

**Author:** ![ak756](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/b5a626/32.png) [@ak756](https://www.ruby-forum.com/u/ak756)\
**Post date:** [August 10, 2007, 11:15am UTC](https://www.ruby-forum.com/t/newbie-question-how-to-seek-in-a-file/111739/5 "2007-08-10T11:15:00Z")

</div>

On Friday 10 August 2007 01:43:13 am Ak 756 wrote:

> I want to find a string in a text file, then read some bytes data after  
> the position of this string. Would anybody kindly help to tell me how to  
> do?

If this is what you really want, you can do something like:

READ\_BYTES = 16  
my\_file\_contents = File.open(‘foo’){|f| f.read }  
my\_file\_contents =~ /find this string(.{#{READ\_BYTES}})/  
my\_data = $1

Of course, this is no good for large files. Generally if you’re trying  
to  
extract data from a large text file though, you should already know  
where it  
is (constant width records) or you have to parse through everything  
before  
the record you want to get at the one you do (csv, xml?).

If this is for a configuration file or some sort of semi-static storage,  
I’d  
recommend using YAML or Marshal instead of making your own parser.

Cheers!

---

<div class="post-metadata">

**Author:** ![ak756](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/b5a626/32.png) [@ak756](https://www.ruby-forum.com/u/ak756)\
**Post date:** [August 10, 2007, 12:02pm UTC](https://www.ruby-forum.com/t/newbie-question-how-to-seek-in-a-file/111739/6 "2007-08-10T12:02:11Z")

</div>

Ak 756 wrote:

> I don’t care about huge file at present and this method works for me.  
> Thanks Konrad and Lutz.  
> I believe you can also do this with RExpect, but I’m on Windows right  
> now and can’t test it out.

---

<div class="post-metadata">

**Author:** ![ak756](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/b5a626/32.png) [@ak756](https://www.ruby-forum.com/u/ak756)\
**Post date:** [August 10, 2007, 11:46am UTC](https://www.ruby-forum.com/t/newbie-question-how-to-seek-in-a-file/111739/7 "2007-08-10T11:46:32Z")

</div>

Konrad M. wrote:

> On Friday 10 August 2007 02:09:56 am Konrad M. wrote:
> 
> > my\_data = $1  
> > Better yet:  
> > READ\_BYTES = 16  
> > content = File.open(‘foo’){|f| f.read }  
> > my\_data = content[content.index(“find this string”), READ\_BYTES]
> 
> # I tried to combine Lutz’s and my earlier ideas
> 
> Though this of course assumes the string is found.

I don’t care about huge file at present and this method works for me.  
Thanks Konrad and Lutz.

---

<div class="post-metadata">

**Author:** ![ak756](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/b5a626/32.png) [@ak756](https://www.ruby-forum.com/u/ak756)\
**Post date:** [August 10, 2007, 1:08pm UTC](https://www.ruby-forum.com/t/newbie-question-how-to-seek-in-a-file/111739/8 "2007-08-10T13:08:22Z")

</div>

2007/8/10, Ak 756 [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> Konrad M. wrote:
> 
> > On Friday 10 August 2007 02:09:56 am Konrad M. wrote:
> > 
> > > my\_data = $1  
> > > Better yet:  
> > > READ\_BYTES = 16  
> > > content = File.open(‘foo’){|f| f.read }  
> > > my\_data = content[content.index(“find this string”), READ\_BYTES]

But be careful because #index returns the starting position of the  
string searched for.

> > # I tried to combine Lutz’s and my earlier ideas
> > 
> > Though this of course assumes the string is found.
> 
> I don’t care about huge file at present and this method works for me.  
> Thanks Konrad and Lutz.

You can even do it in one line:

bytes = File.read(“foo”)[/your\_string(.{10})/, 1]

This reads the file into one String, does one regexp match and returns  
contents of the capturing group which in this case contains arbitrary  
10 characters (i.e. bytes).

Kind regards

robert
