From: Robert Maas, http://tinyurl.com/uh3t
Subject: Re: How to read columns from a file?
Date: 
Message-ID: <rem-2008sep15-001@yahoo.com>
> From: Francogrex <······@grex.org>
> Hello, I have a txt file like below: test.txt (only showing a toy
> example of 3 cols and 5 rows but there may be 1000s of rows).
> jan     sun     12
> feb     mon     14
> mar     fri     23
> aug     sat     3
> jun     tue     15

You need to specify whether the whitespace is tab (single tab
between each adjacent pair of columns), where the nice line-up of
columns is an artifact of tab stops on your output device, or
spaces (varying number of spaces depending on length of preceding
word, where length of preceding word plus number of spaces is a
constant for each particular column), where the nice line-up of
columns is directly caused by the constant total of word+spaces in
each column.

In the former case, you should read-line and split per tabs, else below:

You need to specify whether the word of the previous column can
ever be so large that the number of spaces after it is ZERO because
the number of characters in the word is *already* the total desired
for column plus trailing spaces.

You also need to specify whether you want to hand-code the width of
each column, and if you make the slightest mistake you get very
incorrect results, such as parts of two different columns being
taken as a single word from a single column, or you want the
program to automaticlally adapt to the widths of columns in any
given file so that it's rubust against slight changes in the format
of various files it reads.

For robust adaptive column locations, where there is always at
least one space between adjacent columns, a module I wrote this
past August does the job. Let me know if you are interested in
more info about 2008-8-cols.lisp

> Is there a quick and easy way to read from a txt file each column
> to a list in CL?

If you know a priori how wide each column is, and you *never* will
make a mistake in hand-configuring the column widths, you can use
read-line and then (list (subseq str start1 end1) (subseq str
start2 end2) ...) where the start<n> and end<n> are appropriate
handcoded positions with the line of text. Depending on how many
columns you have, the function to split a single line into those
fields is one or two lines of code. You need a string-trim mapped
down the results most likely. If you need some fields converted to
integers and others left as strings, it's another couple lines of
code. That last trick is where Lisp shines compared to most other
languages:  (mapcar #'funcall <ListOfFunctions> <ListOfStringsInLine>)
Actually you can use the same trick to generate the substrings:
 (mapcar #'(lambda (st en) (subseq str st en))
   <ListOfStartIndexes> <ListOfEndIndexes>)
If you prefer to keep the start-end indexes together as a unit
instead of collated between two lists, then do this instead:
 (mapcar #'(lambda (sten) (subseq str (car sten) (cdr sten)))
   <ListOfStartDotEndIndexes>)
But the advantage of using two collated lists is that you can
format your handcoded lists of indexes like this:
;jan     sun     12
(defparameter *startindexes* '(
 0       8       16))
(defparameter *endindexes* '( ;EndPlusOne is CL convention!
         8       16  18))
so that the sample data comment lines up with the numeric indexes.
Caveat, I haven't tested this skeleton code.
By the way, given that every starting index is a multiple of 8, I
am starting to suspect that you are dealing with tab-delimited data
here, and all my wonderful remarks after the first paragraph are
moot.

One super-trick you can use is to have just a single list of
start/end indexes and pass the CDR of the start-index list as the
end-index-list parameter, because MAPCAR stops whenever *either*
list reaches the end.
;jan     sun     12
(defparameter *cutindexes* '(
 0       8       16 18))
..
 (mapcar #'(lambda (st en) (subseq str st en))
   *cutindexes* (cdr *cutindexes*))

Caveat: If the last column is ragged, there's a bug, which requires
another slight trick to fix, exercise for OP asking help with homework.
Hint: (or somethingThatMightBeNil defaultValue)