Searching Files

Finding lines that contain specified text.

Here is a file containing some text:

FilePrint["ExampleData/textfile"]

This returns a list of all the lines in the file containing the text is:

FindList["ExampleData/textfile","is"]

The text fourth appears nowhere in the file:

FindList["ExampleData/textfile","fourth"]

By default, (RefLink[FindList, paclet:ref/FindList]) scans successive lines of a file, and returns those lines which contain the text you specify. In general, however, you can get (RefLink[FindList, paclet:ref/FindList]) to scan successive records, and return complete records which contain specified text. As in (RefLink[ReadList, paclet:ref/ReadList]), the option (RefLink[RecordSeparators, paclet:ref/RecordSeparators]) allows you to tell the Wolfram Language what strings you want to consider as record separators. Note that by giving a pair of lists as the setting for (RefLink[RecordSeparators, paclet:ref/RecordSeparators]), you can specify different left and right separators. By doing this, you can make (RefLink[FindList, paclet:ref/FindList]) search only for text which is between specific pairs of separators.

This finds all "sentences" ending with a period which contain (RefLink[And, paclet:ref/And]):

FindList["ExampleData/textfile","And",RecordSeparators->{"."}]

Options for (RefLink[FindList, paclet:ref/FindList]).

This finds only the occurrence of (RefLink[Here, paclet:ref/Here]) which is at the beginning of a line in the file:

FindList["ExampleData/textfile","Here",AnchoredSearch->True]

In general, (RefLink[FindList, paclet:ref/FindList]) finds text that appears anywhere inside a record. By setting the option (RefLink[WordSearch, paclet:ref/WordSearch])->(RefLink[True, paclet:ref/True]), however, you can tell (RefLink[FindList, paclet:ref/FindList]) to require that the text it is looking for appears as a separate word in the record. The option (RefLink[WordSeparators, paclet:ref/WordSeparators]) specifies the list of separators for words.

The text th does appear in the file, but not as a word. As a result, the (RefLink[FindList, paclet:ref/FindList]) fails:

FindList["ExampleData/textfile","th",WordSearch->True]

Searching in multiple files.

This searches for third in two copies of textfile:

FindList[{"ExampleData/textfile","ExampleData/textfile"},"third"]

It is often useful to call (RefLink[FindList, paclet:ref/FindList]) on lists of files generated by functions such as (RefLink[FileNames, paclet:ref/FileNames]).

Finding text in the output from an external program.

This runs the external Unix command date in a text-based interface:

!date

This finds the time-of-day field in the date:

FindList["!date",":",RecordSeparators->{" "}]

Finding successive occurrences of text.

(RefLink[FindList, paclet:ref/FindList]) works by making one pass through a particular file, looking for occurrences of the text you specify. Sometimes, however, you may want to search incrementally for successive occurrences of a piece of text. You can do this using (RefLink[Find, paclet:ref/Find]).

In order to use (RefLink[Find, paclet:ref/Find]), you first explicitly have to open an input stream using (RefLink[OpenRead, paclet:ref/OpenRead]). Then, every time you call (RefLink[Find, paclet:ref/Find]) on this stream, it will search for the text you specify, and make the current point in the file be just after the record it finds. As a result, you can call (RefLink[Find, paclet:ref/Find]) several times to find successive pieces of text.

This opens an input stream for textfile:

stext=OpenRead["ExampleData/textfile"]

This finds the first line containing (RefLink[And, paclet:ref/And]):

Find[stext,"And"]

Calling (RefLink[Find, paclet:ref/Find]) again gives you the next line containing (RefLink[And, paclet:ref/And]):

Find[stext,"And"]

This closes the input stream:

Close[stext]

Once you have an input stream, you can mix calls to (RefLink[Find, paclet:ref/Find]), (RefLink[Skip, paclet:ref/Skip]), and (RefLink[Read, paclet:ref/Read]). If you ever call (RefLink[FindList, paclet:ref/FindList]) or (RefLink[ReadList, paclet:ref/ReadList]), the Wolfram Language will immediately read to the end of the input stream.

This opens the input stream:

stext=OpenRead["ExampleData/textfile"]

This finds the first line which contains second, and leaves the current point in the file at the beginning of the next line:

Find[stext,"second"]

(RefLink[Read, paclet:ref/Read]) can then read the word that appears at the beginning of the line:

Read[stext,Word]

This skips over the next three words:

Skip[stext,Word,3]

The Wolfram Language finds is in the remaining text, and prints the entire record as output:

Find[stext,"is"]

This closes the input stream:

Close[stext]

Finding and setting the current point in a stream.

Functions like (RefLink[Read, paclet:ref/Read]), (RefLink[Skip, paclet:ref/Skip]), and (RefLink[Find, paclet:ref/Find]) usually operate on streams in an entirely sequential fashion. Each time one of the functions is called, the current point in the stream moves on.

Sometimes, you may need to know where the current point in a stream is, and be able to reset it. On most computer systems, (RefLink[StreamPosition, paclet:ref/StreamPosition]) returns the position of the current point as an integer giving the number of bytes from the beginning of the stream.

This opens the stream:

stext=OpenRead["ExampleData/textfile"]

When you first open the file, the current point is at the beginning, and (RefLink[StreamPosition, paclet:ref/StreamPosition]) returns 0:

StreamPosition[stext]

This reads the first line in the file:

Read[stext,Record]

Now the current point has advanced:

StreamPosition[stext]

This sets the stream position back:

SetStreamPosition[stext,5]

Now (RefLink[Read, paclet:ref/Read]) returns the remainder of the first line:

Read[stext,Record]

This closes the stream:

Close[stext]