csv2recutil/csv2recutil.md

95 lines
1.6 KiB
Markdown

# csv2recutil
This script takes the path of a <abbr title="comma separated value">CSV</abbr> file as an argument, and prints the data to stdout in [recutils] format
[recutils]: https://www.gnu.org/software/recutils/manual/recutils.html
## Usage
`retro csv2recutil.md file.csv`
Print message if no argument is given:
~~~
script:arguments #0 eq? [ 'Usage:_csv2recutil_<file.csv> s:put nl nl ] if;
~~~
## File reader
open file, get handle and size
~~~
'handle var 'size var
#0 script:get-argument file:open-for-reading !handle !size
~~~
readline utility
~~~
:get-line @handle file:read-line ;
~~~
## CSV to array
declare `s:to-array/csv` function. Takes a string, returns an array.
~~~
:s:to-array/csv (s-a)
~~~
strip all the double quotes. NOTE: this will also strip all quotes in the body text. Might be better to chomp, reverse, chomp, reverse?
~~~
[ $" -eq? ] s:filter
~~~
Finally split on commas
~~~
$, s:tokenize
~~~
There, now you have an array
(end function:)
~~~
;
~~~
## Main
Get the headers:
~~~
get-line s:to-array/csv 'Headers var-n
~~~
declare a var for the current line so we can assign to it
~~~
'Current var
~~~
Print headers and current line as a recutil. (Use `indexed-times` so we can use the index to get the nth element from each array.)
~~~
:print-record
get-line s:to-array/csv !Current
@Headers a:length [
I
dup @Headers swap a:fetch s:put ':_ s:put
@Current swap a:fetch s:put nl
] indexed-times
;
~~~
Now print-record for all the remaining lines in the file
~~~
[
print-record nl
@size @handle file:tell gt?
] while
~~~