in Elfie/Xsv/Program.cs [25:192]
Copy the input to the output (to convert format).
Pass comma delimited column names to copy only specific columns.
Xsv where <input> <columnIdentifier> <operator> <value> <output|cout|"""">
Write the row to the output where the column matches the value.
Omit the output to count results only.
Xsv distinct <input> <columnIdentifier> <output|cout|"""">
Write each distinct value seen in the column in input to the output.
Xsv first <input> <output> <rowCount>
Copy the first <rowCount> rows from input to output.
Xsv append <inputFileOrFolder> <outputToAppendTo> <inputFileNamePattern?>
Append rows from input(s) to an existing output file.
Pass a folder path to merge all files in the folder, as long as columns are the same.
Xsv rowId <input> <output> <firstId?>
Add an incrementing integer ID column as the first column, starting with the provided value or 1.
Xsv concat <input> <output>:
Concatenate values by the first column value, excluding duplicates.
Input must be sorted by the first column to concatenate.
Xsv concatCol <input> <output> <col1> <separator> <col2> <outColName>
Concatenate column values together: out['outColName'] = row['col1'] + separator + row['col2'].
Xsv notStartsWith <input> <output> <valueColumnIndexOrName> <nameColumnIndexOrName>:
Copy the input, excluding rows where row[valueIndex].StartsWith(row[nameIndex]).
Xsv compare <oldInputPath> <newInputPath> <output> <columnIndexOrName>
Compare the set of values for the column between the two inputs and write the differences.
Xsv onlyIn <input> <output> <onlyInFilePath> <onlyInColumnIdentifier>
Copy rows from input to output if the 'onlyInColumnIdentifier' was also found in 'onlyInFilePath'.
Xsv onlyLatest <inputFolder> <outputFile> <idColumnIdentifier>
Copy the last row for each ID from the input folder to the output file, walking inputs alphabetically.
Xsv htmlInnerText <input> <output> <columnIdentifier>
Copy rows from input to output, converting HTML in the column with the inner text equivalent.
Xsv sanitize <input> <output> <specFile> <hashKey>
Sanitize (re-map identifying values) from input to output using specFile rules.
Makes safe sample data from sensitive data by remapping values.
Xsv sanitizeValue <value> <columnName> <specFile> <hashKey>
Translate a single value from a given column. Used to map values to allow
investigations on sanitized data.
";
public static int Main(string[] args)
{
Trace.Listeners.Add(new ConsoleTraceListener());
if (args == null || args.Length < 3)
{
Trace.WriteLine(Usage);
return -1;
}
string mode = args[0].ToLowerInvariant();
try
{
using (new TraceWatch(String.Empty))
{
switch (mode)
{
case "copy":
Trace.WriteLine(String.Format("Copy \"{0}\" to \"{1}\"...", args[1], args[2]));
if (args.Length < 4)
{
Copy(args[1], args[2]);
}
else
{
Copy(args[1], args[2], args[3]);
}
break;
case "first":
if (args.Length < 4) throw new UsageException("first requires an input, output, and row count.");
Trace.WriteLine(String.Format("Getting first {2} rows from \"{0}\" into \"{1}\"...", args[1], args[2], args[3]));
Copy(args[1], args[2], int.Parse(args[3]));
break;
case "distinct":
if (args.Length < 4) throw new UsageException("distinct requires an input, output, and column identifier.");
Trace.WriteLine(String.Format("Writing Distinct values for {2} from \"{0}\" into \"{1}\"...", args[1], args[2], args[3]));
Distinct(args[1], args[2], args[3]);
break;
case "append":
if (args.Length < 3) throw new UsageException("append requires an input and output");
Trace.WriteLine(String.Format("Appending from \"{0}\" to \"{1}\"...", args[1], args[2]));
Append(args[1], args[2], (args.Length > 3 ? args[3] : null));
break;
case "rowid":
if (args.Length < 3) throw new UsageException("rowid requires an input and output");
Trace.WriteLine(String.Format("Adding autoincrementing ID column from \"{0}\" to \"{1}\"...", args[1], args[2]));
RowId(args[1], args[2], (args.Length > 3 ? int.Parse(args[3]) : 1));
break;
case "concat":
Trace.WriteLine(String.Format("Concatenating \"{0}\" values on first column into \"{1}\"...", args[1], args[2]));
Concatenate(args[1], args[2], String8.Convert("; ", new byte[2]));
break;
case "concatcol":
if (args.Length < 7) throw new UsageException("concatCol requires input, output, col1, separator, col2, outColName");
Trace.WriteLine(String.Format("Concatenating \"[{2}] + \"{3}\" + [{4}]\" from \"{0}\" into column \"{5}\" in \"{1}\"...", args[0], args[1], args[2], args[3], args[4], args[5], args[6]));
ConcatenateColumn(args[1], args[2], args[3], args[4], args[5], args[6]);
break;
case "notstartswith":
if (args.Length < 5) throw new UsageException("notStartsWith requires a value and name column to be passed.");
Trace.WriteLine(String.Format("Writing \"{0}\" values into \"{1}\" where !row[{2}].StartsWith(row[{3}])", args[1], args[2], args[3], args[4]));
NotStartsWith(args[1], args[2], args[3], args[4]);
break;
case "compare":
if (args.Length < 5) throw new UsageException("compare requires two input files, an output file, and a column identifier to compare.");
Trace.WriteLine(String.Format("Comparing values for \"{0}\" values between \"{1}\" and \"{2}\"...", args[1], args[2], args[3], args[4]));
Compare(args[1], args[2], args[3], args[4]);
break;
case "onlyin":
if (args.Length < 5) throw new UsageException("onlyIn requires a second input file and column identifier");
Trace.WriteLine(String.Format("Writing \"{0}\" values into \"{1}\" where \"{2}\" also had the same \"{3}\"...", args[1], args[2], args[3], args[4]));
OnlyIn(args[1], args[2], args[3], args[4]);
break;
case "onlylatest":
if (args.Length < 4) throw new UsageException("onlyLatest requires an input folder, output file, and column identifier");
Trace.WriteLine(String.Format("Copying latest rows by \"{2}\" from \"{0}\" into \"{1}\"...", args[1], args[2], args[3]));
OnlyLatest(args[1], args[2], args[3]);
break;
case "sanitize":
if (args.Length < 5) throw new UsageException("sanitize requires input, output, specFile, hashKey");
Trace.WriteLine(String.Format("Sanitizing \"{0}\" into \"{1}\" using \"{2}\"...", args[1], args[2], args[3]));
Xsv.Sanitize.Sanitizer s = new Xsv.Sanitize.Sanitizer(args[3], args[4]);
s.Sanitize(args[1], args[2]);
break;
case "sanitizevalue":
if (args.Length < 5) throw new UsageException("sanitize requires value, columnName, specFile, hashKey");
Trace.WriteLine(String.Format("Sanitizing \"{0}\" from column \"{1}\" using \"{2}\"...", args[1], args[2], args[3]));
Trace.WriteLine(new Xsv.Sanitize.Sanitizer(args[3], args[4]).Translate(args[1], args[2]));
break;
case "htmlinnertext":
if (args.Length < 4) throw new UsageException("htmlInnerText requires an input file, output file, and column identifier");
Trace.WriteLine(String.Format("Converting Html to Text in \"{2}\" from \"{0}\" into \"{1}\"...", args[1], args[2], args[3]));
HtmlInnerText(args[1], args[2], args[3]);
break;
case "where":
if (args.Length < 3) throw new UsageException("where requires input, column, operator, value");
Where(args[1], args[2], args[3], args[4], (args.Length > 5 ? args[5] : null));
break;
default:
throw new NotSupportedException(String.Format("XSV mode \"{0}\" is unknown. Run without arguments to see valid modes.", mode));
}
}
return 0;
}
catch (UsageException ex)
{
Trace.WriteLine(ex.Message);
Trace.WriteLine(Usage);
return -2;
}
catch (Exception ex) when (!Debugger.IsAttached)
{
Trace.WriteLine("ERROR: " + ex.ToString());
return -1;
}
}