diff --git a/csv-merger/pom.xml b/csv-merger/pom.xml
new file mode 100644
index 0000000..50ef822
--- /dev/null
+++ b/csv-merger/pom.xml
@@ -0,0 +1,18 @@
+
+
+ 4.0.0
+
+ twopm.tech.jax-rs-bench
+ bom
+ 1.0-SNAPSHOT
+
+ csv-merger
+ jar
+
+
+ org.apache.commons
+ commons-csv
+ 1.9.0
+
+
+
\ No newline at end of file
diff --git a/csv-merger/src/main/java/twopm/tech/jaxrsbench/csv/merger/Merger.java b/csv-merger/src/main/java/twopm/tech/jaxrsbench/csv/merger/Merger.java
new file mode 100644
index 0000000..a5d7b35
--- /dev/null
+++ b/csv-merger/src/main/java/twopm/tech/jaxrsbench/csv/merger/Merger.java
@@ -0,0 +1,82 @@
+package twopm.tech.jaxrsbench.csv.merger;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.Reader;
+import static java.lang.System.in;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import org.apache.commons.csv.CSVFormat;
+import org.apache.commons.csv.CSVPrinter;
+import org.apache.commons.csv.CSVRecord;
+
+/**
+ *
+ * @author Edward M. Kagan {@literal <}kaganem{@literal @}2pm.tech{@literal >}
+ */
+public class Merger {
+
+ public static final void main(String[] args) throws FileNotFoundException, IOException {
+ if (args.length != 1) {
+ System.err.println("I need exactly one argument!");
+ System.exit(-1);
+ }
+ File dataDir = new File(args[0]);
+ if (!dataDir.exists()) {
+ System.err.println("Directory '" + dataDir.getPath() + "' does not exist!");
+ System.exit(-2);
+ }
+
+ File[] files = dataDir.listFiles(new FilenameFilter() {
+ @Override
+ public boolean accept(File file, String name) {
+ return new File(file, name).isFile() && name.endsWith(".csv");
+ }
+ });
+
+ BufferedWriter writer = new BufferedWriter(new FileWriter(new File(dataDir, "merged.csv")));
+ CSVPrinter csvPrinter = null;
+ boolean headerRow;
+
+ for (File file : files) {
+ Reader in = new FileReader(file);
+
+ headerRow = true;
+ Iterable records = CSVFormat.RFC4180.parse(in);
+ for (CSVRecord record : records) {
+ if (headerRow) {
+ if (csvPrinter == null) {
+ String[] header = new String[4 + record.size()];
+ header[0]="action";
+ header[1]="version";
+ header[2]="module";
+ header[3]="jdk";
+
+ for (int col = 0; col < record.size(); col++) {
+ header[4 + col] = record.get(col);
+ }
+ csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT.withHeader(header));
+ System.out.println(csvPrinter);
+ }
+ } else {
+ String[] prefix = file.getName().replace(".csv", "").split("_");
+ String[] row = new String[4 + record.size()];
+ for (int col = 0; col < record.size(); col++) {
+ row[4 + col] = record.get(col);
+ }
+ System.arraycopy(prefix, 0, row, 0, prefix.length);
+ csvPrinter.printRecord(row);
+ }
+ if (headerRow) headerRow = !headerRow;
+ }
+ }
+ if (csvPrinter != null) {
+ csvPrinter.flush();
+ }
+ }
+}