// grep - Search stdin or some files for lines matching a given string. use std::error::Error; use std::io::{self, BufReader}; use std::io::prelude::*; use std::fs::File; use std::path::PathBuf; fn grep(target: &str, reader: R) -> io::Result<()> where R: BufRead { for line_result in reader.lines() { let line = line_result?; if line.contains(target) { println!("{}", line); } } Ok(()) } fn grep_main() -> Result<(), Box> { // Get the command-line arguments. The first argument is the // string to search for; the rest are filenames. let mut args = std::env::args().skip(1); let target = match args.next() { Some(s) => s, None => Err("usage: grep PATTERN FILE...")? }; let files: Vec = args.map(PathBuf::from).collect(); if files.is_empty() { let stdin = io::stdin(); grep(&target, stdin.lock())?; } else { for file in files { let f = File::open(file)?; grep(&target, BufReader::new(f))?; } } Ok(()) } fn main() { let result = grep_main(); if let Err(err) = result { eprintln!("{}", err); std::process::exit(1); } }