use std::fs;
use std::io::BufRead;
use std::io::Write;
use std::io;
use std::env;
fn replace_col(inpath: &str, outpath: &str, column: &str,
replacement: &str) -> io::Result<()>
{
let infile = fs::File::open(inpath)?;
let reader = io::BufReader::new(infile);
let outfile = fs::File::create(outpath)?;
let mut writer = io::BufWriter::new(outfile);
let mut replacenum: usize = 0;
let mut lines = reader.lines();
// handle header
if let Some(line) = lines.next() { // could be empty file
let header = line?; // could be IO error
let mut splitted = header.split(',');
// search for column label
if let Some(colnum) = splitted.position(|colname| colname == column) {
replacenum = colnum;
}
else {
return Err(io::Error::new(
io::ErrorKind::InvalidData, "Column not found"));
}
// pass header through unchanged
writer.write_fmt(format_args!("{}\n", header))?;
}
for line in lines {
let content = line?; // could be IO error
let splitted = content.splitn(replacenum + 2, ',');
// figure out where to insert the replacement string
let mut replaced = splitted.enumerate()
.map(|(colnum, orig)|
if colnum == replacenum { replacement }
else { orig });
// first column
if let Some(value) = replaced.next() { // could be empty string
writer.write(value.as_bytes())?;
}
// all following columns. Include comma separator
for value in replaced {
writer.write_fmt(format_args!(",{}", value))?;
}
writer.write(b"\n")?;
}
writer.flush()?;
Ok({})
}
fn main()
{
let mut args = env::args().skip(1); // skip program name
let inpath = args.next().expect("Need input file path");
let column = args.next().expect("Need column label");
let replacement = args.next().expect("Need replacement value");
let outpath = args.next().expect("Need output file path");
replace_col(&inpath, &outpath, &column, &replacement).expect("IO Error");
}
Comments