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"); }