From c9a81306edca20c61f62206d4f49580a2087fc05 Mon Sep 17 00:00:00 2001 From: rich Date: Tue, 5 Dec 2006 22:24:44 +0000 Subject: [PATCH] Added 'csvtool call' which allows neat integration with shell scripts. --- csvtool.ml | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/csvtool.ml b/csvtool.ml index d944160..724eb72 100644 --- a/csvtool.ml +++ b/csvtool.ml @@ -1,5 +1,5 @@ (* Handy tool for managing CSV files. - * $Id: csvtool.ml,v 1.8 2006-11-24 15:49:24 rich Exp $ + * $Id: csvtool.ml,v 1.9 2006-12-05 22:24:44 rich Exp $ *) open Printf @@ -303,6 +303,24 @@ let cmd_replace ~input_sep ~output_sep ~chan colspec update files = let csv = csv @ update in save_out ~separator:output_sep chan csv +let cmd_call ~input_sep ~output_sep ~chan command files = + (* Avoid loading the whole file into memory. *) + let f row = + let cmd = + command ^ " " ^ String.concat " " (List.map Filename.quote row) in + let code = Sys.command cmd in + if code <> 0 then ( + eprintf "%s: terminated with exit code %d\n" command code; + exit code + ) + in + List.iter ( + fun filename -> + let in_chan = open_in filename in + load_rows ~separator:input_sep f in_chan; + close_in in_chan + ) files + let rec uniq = function | [] -> [] | [x] -> [x] @@ -439,7 +457,8 @@ Commands: Example: csvtool join 1 2 coll1.csv coll2.csv > output.csv - If coll1.csv contains: + + In the above example, if coll1.csv contains: Computers,$40 Software,$100 and coll2.csv contains: @@ -467,6 +486,36 @@ Commands: csvtool replace 3 updates.csv original.csv > new.csv mv new.csv original.csv + call command + This calls the external command (or shell function) 'command' + followed by a parameter for each column in the CSV file. The + external command is called once for each row in the CSV file. + If any command returns a non-zero exit code then the whole + program terminates. + + Tip: + Use the shell command 'export -f funcname' to export + a shell function for use as a command. Within the + function, use the positional parameters $1, $2, ... + to refer to the columns. + + Example (with a shell function): + function test { + echo Column 1: $1 + echo Column 2: $2 + } + export -f test + csvtool call test my.csv + + In the above example, if my.csv contains: + how,now + brown,cow + then the output is: + Column 1: how + Column 2: now + Column 1: brown + Column 2: cow + readable Print the input CSV in a readable format. @@ -597,6 +646,8 @@ let () = | "drop" :: rows :: files -> let rows = int_of_string rows in cmd_drop ~input_sep ~output_sep ~chan rows files + | "call" :: command :: files -> + cmd_call ~input_sep ~output_sep ~chan command files | _ -> prerr_endline (Sys.executable_name ^ " --help for usage"); exit 2 -- 1.8.3.1