'csvtool replace' command.
authorrich <rich>
Tue, 6 Jun 2006 16:01:52 +0000 (16:01 +0000)
committerrich <rich>
Tue, 6 Jun 2006 16:01:52 +0000 (16:01 +0000)
Bumped version number for release.

Makefile
csvtool.ml

index 6d30f56..3366db2 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
-# $Id: Makefile,v 1.7 2005-11-25 14:08:46 rich Exp $
+# $Id: Makefile,v 1.8 2006-06-06 16:01:52 rich Exp $
 
 PACKAGE                := ocaml-csv
-VERSION                := 1.1.0
+VERSION                := 1.1.1
 
 OCAMLC         := ocamlc
 OCAMLCINCS     :=
index 1cee449..8ad7ee9 100644 (file)
@@ -1,5 +1,5 @@
 (* Handy tool for managing CSV files.
- * $Id: csvtool.ml,v 1.2 2005-11-25 14:06:58 rich Exp $
+ * $Id: csvtool.ml,v 1.3 2006-06-06 16:01:52 rich Exp $
  *)
 
 open Printf
@@ -57,9 +57,42 @@ let cmd_sub ~separator ~csv ~chan args =
   let csv = sub r c rows cols csv in
   save_out ~separator chan csv
 
+let cmd_replace ~separator ~csv ~chan args =
+  let ncols, replacement =
+    match args with
+    | [ ncols; replacement ] -> int_of_string ncols, replacement
+    | _ ->
+       failwith "unknown arguments to 'replace' command" in
+  (* Load the replacement CSV file in. *)
+  let replacement = Csv.load ~separator replacement in
+
+  (* Compare two rows for equality be considering only the first ncols. *)
+  let rec compare ncols row1 row2 =
+    if ncols <= 0 then true
+    else
+      match row1, row2 with
+      | [], [] -> true
+      | [], _ -> false
+      | _, [] -> false
+      | x :: xs, y :: ys ->
+         let c = Pervasives.compare x y in
+         if c <> 0 then false
+         else
+           compare (ncols-1) xs ys
+  in
+
+  (* Look for rows in the original to be replaced by rows from the
+   * replacement file.  This is an ugly O(n^2) hack (XXX).
+   *)
+  let csv = List.filter (
+    fun row -> not (List.exists (compare ncols row) replacement)
+  ) csv in
+  let csv = csv @ replacement in
+  save_out ~separator chan csv
+
 (* Process the arguments. *)
 let usage =
-  "csvtool - Copyright (C) 2005 Richard W.M. Jones, Merjis Ltd.
+  "csvtool - Copyright (C) 2005-2006 Richard W.M. Jones, Merjis Ltd.
 
 csvtool is a tool for performing manipulations on CSV files from shell scripts.
 
@@ -92,6 +125,11 @@ Commands:
     Take a square subset of the CSV, top left at row r, column c (counting
     from 0), which is rows deep and cols wide.
 
+  replace ncols file.csv
+    Replace rows in input.csv with rows from file.csv.  The first ncols
+    columns only are used to compare rows in input.csv and file.csv to
+    see if they are candidates for replacement.
+
 Input and output files:
   csvtool normally processes its input from stdin and writes its output
   to stdout.  Use the -i and -o options to override this behaviour.
@@ -170,6 +208,8 @@ let () =
         cmd_square ~separator:output_sep ~csv:input ~chan ()
      | "sub" ->
         cmd_sub ~separator:output_sep ~csv:input ~chan args
+     | "replace" ->
+        cmd_replace ~separator:output_sep ~csv:input ~chan args
      | _ -> prerr_endline (Sys.executable_name ^ " --help for usage")
   );