Skip to content

Commit

Permalink
Add support for XSV_TOGGLE_HEADERS and inferring a tab
Browse files Browse the repository at this point in the history
delimiter for tsv files.

Also, '\t' can now be used as an argument to --delimiter.
  • Loading branch information
BurntSushi committed Dec 6, 2014
1 parent 38f492c commit bf8f741
Show file tree
Hide file tree
Showing 19 changed files with 87 additions and 68 deletions.
4 changes: 2 additions & 2 deletions src/cmd/cat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Common options:
as column names. Note that this has no effect when
concatenating columns.
-d, --delimiter <arg> The field delimiter for reading CSV data.
Must be a single character. [default: ,]
Must be a single character. (default: ,)
";

#[deriving(Decodable)]
Expand All @@ -48,7 +48,7 @@ struct Args {
flag_pad: bool,
flag_output: Option<String>,
flag_no_headers: bool,
flag_delimiter: Delimiter,
flag_delimiter: Option<Delimiter>,
}

pub fn run(argv: &[&str]) -> CliResult<()> {
Expand Down
6 changes: 3 additions & 3 deletions src/cmd/count.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ Common options:
-n, --no-headers When set, the first row will not be included in
the count.
-d, --delimiter <arg> The field delimiter for reading CSV data.
Must be a single character. [default: ,]
Must be a single character. (default: ,)
";

#[deriving(Decodable)]
struct Args {
arg_input: Option<String>,
flag_no_headers: bool,
flag_delimiter: Delimiter,
flag_delimiter: Option<Delimiter>,
}

pub fn run(argv: &[&str]) -> CliResult<()> {
Expand All @@ -50,7 +50,7 @@ pub fn run(argv: &[&str]) -> CliResult<()> {
}
}
}
if !args.flag_no_headers && count > 0 {
if !conf.no_headers && count > 0 {
count - 1
} else {
count
Expand Down
4 changes: 2 additions & 2 deletions src/cmd/fixlengths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@ Common options:
-h, --help Display this message
-o, --output <file> Write output to <file> instead of stdout.
-d, --delimiter <arg> The field delimiter for reading CSV data.
Must be a single character. [default: ,]
Must be a single character. (default: ,)
";

#[deriving(Decodable)]
struct Args {
arg_input: Option<String>,
flag_length: Option<uint>,
flag_output: Option<String>,
flag_delimiter: Delimiter,
flag_delimiter: Option<Delimiter>,
}

pub fn run(argv: &[&str]) -> CliResult<()> {
Expand Down
6 changes: 3 additions & 3 deletions src/cmd/flatten.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Common options:
as headers. When set, the name of each field
will be its index.
-d, --delimiter <arg> The field delimiter for reading CSV data.
Must be a single character. [default: ,]
Must be a single character. (default: ,)
";

#[deriving(Decodable)]
Expand All @@ -43,7 +43,7 @@ struct Args {
flag_condensed: Option<uint>,
flag_separator: String,
flag_no_headers: bool,
flag_delimiter: Delimiter,
flag_delimiter: Option<Delimiter>,
}

pub fn run(argv: &[&str]) -> CliResult<()> {
Expand All @@ -64,7 +64,7 @@ pub fn run(argv: &[&str]) -> CliResult<()> {
first = false;
let r = try!(r).into_iter();
for (i, (header, field)) in headers.iter().zip(r).enumerate() {
if args.flag_no_headers {
if rconfig.no_headers {
try!(wtr.write_str(i.to_string().as_slice()));
} else {
try!(wtr.write(&**header));
Expand Down
8 changes: 4 additions & 4 deletions src/cmd/fmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,25 @@ Usage:
fmt options:
-t, --out-delimiter <arg> The field delimiter for writing CSV data.
[default: ,]
(default: ,)
--crlf Use '\\r\\n' line endings in the output.
--ascii Use ASCII field and record separators.
Common options:
-h, --help Display this message
-o, --output <file> Write output to <file> instead of stdout.
-d, --delimiter <arg> The field delimiter for reading CSV data.
Must be a single character. [default: ,]
Must be a single character. (default: ,)
";

#[deriving(Decodable)]
struct Args {
arg_input: Option<String>,
flag_out_delimiter: Delimiter,
flag_out_delimiter: Option<Delimiter>,
flag_crlf: bool,
flag_ascii: bool,
flag_output: Option<String>,
flag_delimiter: Delimiter,
flag_delimiter: Option<Delimiter>,
}

pub fn run(argv: &[&str]) -> CliResult<()> {
Expand Down
7 changes: 4 additions & 3 deletions src/cmd/frequency.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ Common options:
column will be 1-based indices instead of header
names.
-d, --delimiter <arg> The field delimiter for reading CSV data.
Must be a single character. [default: ,]
Must be a single character. (default: ,)
";

#[deriving(Clone, Decodable)]
Expand All @@ -68,11 +68,12 @@ struct Args {
flag_jobs: uint,
flag_output: Option<String>,
flag_no_headers: bool,
flag_delimiter: Delimiter,
flag_delimiter: Option<Delimiter>,
}

pub fn run(argv: &[&str]) -> CliResult<()> {
let args: Args = try!(util::get_args(USAGE, argv));
let rconfig = args.rconfig();

let mut wtr = try!(Config::new(&args.flag_output).writer());
let (headers, tables) = try!(match try!(args.rconfig().indexed()) {
Expand All @@ -83,7 +84,7 @@ pub fn run(argv: &[&str]) -> CliResult<()> {
try!(wtr.write(vec!["field", "value", "count"].into_iter()));
let head_ftables = headers.into_iter().zip(tables.into_iter());
for (i, (mut header, ftab)) in head_ftables.enumerate() {
if args.flag_no_headers {
if rconfig.no_headers {
header = ByteString::from_bytes((i+1).to_string());
}
for (value, count) in args.counts(&ftab).into_iter() {
Expand Down
4 changes: 2 additions & 2 deletions src/cmd/headers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@ headers options:
Common options:
-h, --help Display this message
-d, --delimiter <arg> The field delimiter for reading CSV data.
Must be a single character. [default: ,]
Must be a single character. (default: ,)
";

#[deriving(Decodable)]
struct Args {
arg_input: Vec<String>,
flag_just_names: bool,
flag_intersect: bool,
flag_delimiter: Delimiter,
flag_delimiter: Option<Delimiter>,
}

pub fn run(argv: &[&str]) -> CliResult<()> {
Expand Down
15 changes: 8 additions & 7 deletions src/cmd/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::io::{BufferedWriter, File};
use csv;

use CliResult;
use config::Delimiter;
use config::{Config, Delimiter};
use util;

static USAGE: &'static str = "
Expand All @@ -29,26 +29,27 @@ index options:
Common options:
-h, --help Display this message
-d, --delimiter <arg> The field delimiter for reading CSV data.
Must be a single character. [default: ,]
Must be a single character. (default: ,)
";

#[deriving(Decodable)]
struct Args {
arg_input: String,
flag_output: Option<String>,
flag_delimiter: Delimiter,
flag_delimiter: Option<Delimiter>,
}

pub fn run(argv: &[&str]) -> CliResult<()> {
let args: Args = try!(util::get_args(USAGE, argv));

let pcsv = Path::new(args.arg_input.as_slice());
let pidx = match args.flag_output {
None => util::idx_path(&pcsv),
None => util::idx_path(&Path::new(args.arg_input.as_slice())),
Some(p) => Path::new(p),
};
let rdr = csv::Reader::from_reader(try!(File::open(&pcsv)))
.delimiter(args.flag_delimiter.to_byte());

let rconfig = Config::new(&Some(args.arg_input))
.delimiter(args.flag_delimiter);
let rdr = try!(rconfig.reader_file());
let idx = BufferedWriter::new(try!(File::create(&pidx)));
let _ = try!(csv::index::create(rdr, idx));
Ok(())
Expand Down
6 changes: 3 additions & 3 deletions src/cmd/join.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ Common options:
as headers. (i.e., They are not searched, analyzed,
sliced, etc.)
-d, --delimiter <arg> The field delimiter for reading CSV data.
Must be a single character. [default: ,]
Must be a single character. (default: ,)
";

#[deriving(Decodable)]
Expand All @@ -82,7 +82,7 @@ struct Args {
flag_no_headers: bool,
flag_no_case: bool,
flag_nulls: bool,
flag_delimiter: Delimiter,
flag_delimiter: Option<Delimiter>,
}

pub fn run(argv: &[&str]) -> CliResult<()> {
Expand Down Expand Up @@ -303,7 +303,7 @@ impl Args {
sel1: sel1.normal(),
rdr2: rdr2,
sel2: sel2.normal(),
no_headers: self.flag_no_headers,
no_headers: rconf1.no_headers,
casei: self.flag_no_case,
nulls: self.flag_nulls,
})
Expand Down
4 changes: 2 additions & 2 deletions src/cmd/sample.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Common options:
first row is the header row and will always appear
in the output.)
-d, --delimiter <arg> The field delimiter for reading CSV data.
Must be a single character. [default: ,]
Must be a single character. (default: ,)
";

#[deriving(Decodable)]
Expand All @@ -36,7 +36,7 @@ struct Args {
arg_sample_size: uint,
flag_output: Option<String>,
flag_no_headers: bool,
flag_delimiter: Delimiter,
flag_delimiter: Option<Delimiter>,
}

pub fn run(argv: &[&str]) -> CliResult<()> {
Expand Down
6 changes: 3 additions & 3 deletions src/cmd/search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Common options:
as headers. (i.e., They are not searched, analyzed,
sliced, etc.)
-d, --delimiter <arg> The field delimiter for reading CSV data.
Must be a single character. [default: ,]
Must be a single character. (default: ,)
";

#[deriving(Decodable)]
Expand All @@ -38,7 +38,7 @@ struct Args {
flag_select: SelectColumns,
flag_output: Option<String>,
flag_no_headers: bool,
flag_delimiter: Delimiter,
flag_delimiter: Option<Delimiter>,
}

pub fn run(argv: &[&str]) -> CliResult<()> {
Expand All @@ -56,7 +56,7 @@ pub fn run(argv: &[&str]) -> CliResult<()> {
let nsel = try!(rconfig.normal_selection(headers[]));

let mut wrote_headers = false;
if args.flag_no_headers { wrote_headers = true; }
if rconfig.no_headers { wrote_headers = true; }
for row in rdr.records() {
let row = try!(row);
if nsel.select(row.iter()).any(|f| pattern.is_match(f[])) {
Expand Down
6 changes: 3 additions & 3 deletions src/cmd/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Common options:
as headers. (i.e., They are not searched, analyzed,
sliced, etc.)
-d, --delimiter <arg> The field delimiter for reading CSV data.
Must be a single character. [default: ,]
Must be a single character. (default: ,)
";

#[deriving(Decodable)]
Expand All @@ -24,7 +24,7 @@ struct Args {
arg_selection: SelectColumns,
flag_output: Option<String>,
flag_no_headers: bool,
flag_delimiter: Delimiter,
flag_delimiter: Option<Delimiter>,
}

pub fn run(argv: &[&str]) -> CliResult<()> {
Expand All @@ -41,7 +41,7 @@ pub fn run(argv: &[&str]) -> CliResult<()> {
let headers = try!(rdr.byte_headers());
let sel = try!(rconfig.selection(headers[]));

if !args.flag_no_headers {
if !rconfig.no_headers {
try!(wtr.write_bytes(sel.select(headers[])));
}
for r in rdr.byte_records() {
Expand Down
4 changes: 2 additions & 2 deletions src/cmd/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Common options:
as headers. Otherwise, the first row will always
appear in the output as the header row.
-d, --delimiter <arg> The field delimiter for reading CSV data.
Must be a single character. [default: ,]
Must be a single character. (default: ,)
";

#[deriving(Decodable)]
Expand All @@ -50,7 +50,7 @@ struct Args {
flag_index: Option<uint>,
flag_output: Option<String>,
flag_no_headers: bool,
flag_delimiter: Delimiter,
flag_delimiter: Option<Delimiter>,
}

pub fn run(argv: &[&str]) -> CliResult<()> {
Expand Down
4 changes: 2 additions & 2 deletions src/cmd/sort.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Common options:
of the rows. Otherwise, the first row will always
appear as the header row in the output.
-d, --delimiter <arg> The field delimiter for reading CSV data.
Must be a single character. [default: ,]
Must be a single character. (default: ,)
";

#[deriving(Decodable)]
Expand All @@ -34,7 +34,7 @@ struct Args {
flag_select: SelectColumns,
flag_output: Option<String>,
flag_no_headers: bool,
flag_delimiter: Delimiter,
flag_delimiter: Option<Delimiter>,
}

pub fn run(argv: &[&str]) -> CliResult<()> {
Expand Down
6 changes: 3 additions & 3 deletions src/cmd/split.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Common options:
as column names. Otherwise, the first row will
appear in all chunks as the header row.
-d, --delimiter <arg> The field delimiter for reading CSV data.
Must be a single character. [default: ,]
Must be a single character. (default: ,)
";

#[deriving(Clone, Decodable)]
Expand All @@ -48,7 +48,7 @@ struct Args {
flag_jobs: uint,
flag_output: Option<String>,
flag_no_headers: bool,
flag_delimiter: Delimiter,
flag_delimiter: Option<Delimiter>,
}

pub fn run(argv: &[&str]) -> CliResult<()> {
Expand Down Expand Up @@ -115,7 +115,7 @@ impl Args {
let path = dir.join(format!("{}.csv", start));
let spath = Some(path.display().to_string());
let mut wtr = try!(Config::new(&spath).writer());
if !self.flag_no_headers {
if !self.rconfig().no_headers {
try!(wtr.write_bytes(headers.iter().map(|f| f[])));
}
Ok(wtr)
Expand Down
4 changes: 2 additions & 2 deletions src/cmd/stats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ Common options:
as column names. i.e., They will be included
in statistics.
-d, --delimiter <arg> The field delimiter for reading CSV data.
Must be a single character. [default: ,]
Must be a single character. (default: ,)
";

#[deriving(Clone, Decodable)]
Expand All @@ -75,7 +75,7 @@ struct Args {
flag_jobs: uint,
flag_output: Option<String>,
flag_no_headers: bool,
flag_delimiter: Delimiter,
flag_delimiter: Option<Delimiter>,
}

pub fn run(argv: &[&str]) -> CliResult<()> {
Expand Down
Loading

0 comments on commit bf8f741

Please sign in to comment.