# How to remove an expression from a file?

To read in expressions from a file, one can do ReadList[file, Expression, 3]. How to do the opposite, i.e. remove a number of expressions from a file, modifying the file on the disk?

-

## 2 Answers

Functions like Read, Skip and 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.

In a Sequential file you can´t delete entries. The only option is shifting the "tail" of the file upwards.

-
What does "shifting the 'tail' of the file upwards" mean? – qazwsx Apr 30 '12 at 3:38
@MaThEmAtika Please see figure – belisarius has settled Apr 30 '12 at 3:46
How do you "shift the 'tail' of the file upwards" by a Mathematica program? – qazwsx Apr 30 '12 at 4:39
@MaThEmAtika I guess the easiest way is to copy (replicate) the whole file without the "deleted" elements. If the file is too big for that, perhaps there are other ways. Let us know – belisarius has settled Apr 30 '12 at 5:01
If I always know where the expression I want to delete is in the file, is the best approach reading in the whole file (ReadList[file, Expression]), deleting the expression in memory (Drop[list, 4]), then rewriting the resultant expression back into file (Write[...])? – qazwsx Apr 30 '12 at 5:11

A filtered stream reading function:

Clear[MakeFilteredReader];
Options[MakeFilteredReader] = {Omit -> None};
MakeFilteredReader[stream_InputStream, OptionsPattern[]] :=
Module[{omitList = OptionValue@Omit, position = 0},
Function[s, position += 1;
If[MemberQ[omitList, position],
Skip[stream, s];,
Read[stream, s]]
]
]


Define a stream to read.

str = StringToStream["103 123456 234 456 34"];


Create a reader on that stream.

fr = MakeFilteredReader[str, Omit -> {2, 3}];


Read from the filtered stream reader.

{fr[Number], fr[Number], fr[Number], fr[Number], fr[Number],  fr[Number]}


Which returns:

{103, Null, Null, 456, 34, EndOfFile}

-
My goal is to have the file modified such that expressions at certain indices are removed, not actually selectively reading expressions from file into memory. But as I said earlier, one can read expressions into memory, alter it, and rewrite the whole file. The main thing I am seeking optimization for is to somehow avoid rewriting much of the unchanged expressions back into file. – qazwsx Apr 30 '12 at 22:55
I.e. I'd like to find ways to avoid the trip to memory for the expressions that won't need change/deletetion. – qazwsx May 1 '12 at 17:09
@MaThEmAtika Doesn't preventing the read into memory (I'm not sure if you can easily avoid the low level buffered read that may lurk beneath Mathematica, maybe someone knows if Skip drops it's input before committing to Mathematica's managed memory ) require that you know beforehand the structure of the file? I'm not sure that this meta data on structure is available. – image_doctor May 2 '12 at 17:08
We can make one assumption about the file's data structure that the file contain a sequence of mathematica expressions, separated by newline character. And I know I want to remove the $n^{th}$ expression, for example. – qazwsx May 2 '12 at 17:12
Would preprocessing the file to add/encapsulate meta date about the structure be possible ? – image_doctor May 2 '12 at 17:22