How do I save a table to delimited text?

One way, if the format you want is csv, is automatically invoked when using the save function if the name of the destination file ends in .csv:

q)t: ([] x: `a`b; y: 1 2)
q)save `:t.csv
q)\cat t.csv
“x,y”
“a,1”
“b,2”
q)

For other delimiters, you must first format the text using the overload of the 0: function whose first parameter is a character:

q)t: ([] x: `a`b; y: 1 2)
q)”|” 0: t
“x|y”
“a|1”
“b|2”
q)

Notice that, by default, q saves the table column names as a header in the first line of the file. If you want to get rid of the header line, use _ (drop):

q)t: ([] x: `a`b; y: 1 2)
q)1 _ “\t” 0: t
“a\t1”
“b\t2”
q)

Once you have your data as a list of strings complete with delimiters, you use another overload of the 0: function to save the data to disk; this time, the first parameter is the file handle (name) of the destination file:

q)t: ([] x: `a`b; y: 1 2)
q)`:filename.psv 0: 1 _ “|” 0: t
`:filename.psv
q)\cat filename.psv
“a|1”
“b|2”
q)

Since we can’t seem to keep all of the overloads for 0: straight (there are more we didn’t cover here), we like to wrap the above idiom in a function with a descriptive name. For example,

SaveTableDataAsText: {[path; table; delimiter] hsym[path] 0: 1 _ delimiter 0: table}

See also: .h.cd