Ali A
Ali A

Reputation: 99

writing (& re-arranging) parts of a data file to another file

I have a .dat file with certain data inside it (text, numbers, etc.). The structure of this data file is in the form of blocks of information which start with a line containing the phrase "patch n" with n being the block's number:

patch 0
-----
-----
patch 1
-----
-----
-----
.
.
patch 3
-----

Now, I want to re-arrange the blocks and write them in a new order (wrt the patch number) to another file. This new order is defined in a list such as new-order = (3 1 0 2). Also the line number of the first line of each block (in initial file) is defined in a list such as line-numbers = (0 24 134 210 520).

My question is a good way to code this in common-lisp. I have written the following code but after some of the data is written to the new file, apparently the process falls into an endless loop which I have to stop myself without getting the results:

(with-open-file (out output-stream
                     :direction :output
                     :if-exists :new-version
                     :if-does-not-exist :create)
  (with-open-file (in input-stream
                      :direction :input
                      :if-does-not-exist nil)
    (let ((new-order (list 3 1 0 2)))
      (dotimes (n (length new-order))
        (loop for line = (read-line in nil 'eof)
              for i from 1
              do (when (<= (nth (nth n new-order) line-numbers)
                           i
                           (nth (1+ (nth n new-order)) line-numbers))
                   (format out "~a~%" line)))))))

This is clearly not an efficient way and I was wondering what is causing this problem and what would be the best way to this?

Upvotes: 1

Views: 84

Answers (1)

Svante
Svante

Reputation: 51501

The primary problem seems to be that you need to reset the file position after each pass. The infinite loop happens because you never check for the file end (and suppressed the signal).

Side hint: use dolist instead of that dotimes and nth construction.

If you do not want to make n passes (n being the number of patches), and you cannot hold the entire contents in memory, you could write the patches to temporary files, then concatenate them in the desired order. If you also do not have enough disk space, it becomes an in-place sort problem with varying element sizes, which is a bit more involved.

Upvotes: 2

Related Questions