Rust实现grep命令行工具的方法
短信预约 -IT技能 免费直播动态提醒
一、功能:
1、输入要查询的字符串
和文件名
,输出所有匹配的行的内容
2、如果设置环境变量IGNORE_CASE
,则grep匹配将忽略大小写
3、可使用 >
符号来重定向标准输出到指定文件中
二、介绍
2.1 使用到的知识:
- 读取命令行参数
- 读取文件内容
- 错误处理
- Test Driven Development(TDD)
- 使用环境变量控制不同行为
2.2 代码
1、main.rs
use std::env;
use std::process;
use minigrep::Config;
fn main() {
// let args: Vec<String> = env::args().collect();
// let query = &args[1];
// let filename = &args[2];
// let content = fs::read_to_string(filename).expect("You have a problem in read a file");
// println!("Filename: {}", filename);
// println!("File content:\n{}", content);
//refactoring after
let args: Vec<String> = env::args().collect();
// let config = Config::new(&args);
let config = Config::new(&args).unwrap_or_else(|err| {
eprintln!("Problem parse arguments: {}", err);
process::exit(1);
});
println!("query: {}, filename: {}", config.query, config.filename);
if let Err(e) = minigrep::run(config) {
eprintln!("Application Error: {}", e);
process::exit(1);
}
}
2、lib.rs
use std::error::Error;
use std::fs;
use std::env;
pub struct Config {
pub query: String,
pub filename: String,
pub ignore_case: bool,
}
impl Config {
// fn new(args: &[String]) -> Config {
// let query = args[1].clone();
// let filename = args[2].clone();
// Config {query, filename}
// }
pub fn new(args: &[String]) -> Result<Config, &'static str> {
if args.len() < 3 {
return Err("No enough arguments");
}
let query = args[1].clone();
let filename = args[2].clone();
let ignore_case = env::var("IGNORE_CASE").is_ok();
Ok(Config{query, filename, ignore_case})
}
}
pub fn run(config: Config) -> Result<(), Box<dyn Error>> {
let content = fs::read_to_string(config.filename)?;
// println!("With text:\n{}", content);
let result = if config.ignore_case {
search_case_insensitive(&config.query, &content)
} else {
search(&config.query, &content)
};
for line in result {
println!("{}", line);
}
Ok(())
}
pub fn search<'a>(query: &str, content: &'a str) -> Vec<&'a str> {
let mut result = Vec::new();
for line in content.lines() {
if line.contains(query) {
result.push(line);
}
}
result
}
pub fn search_case_insensitive<'a>(query: &str, content: &'a str) -> Vec<&'a str> {
let mut result = Vec::new();
let query = query.to_lowercase();
for line in content.lines() {
if line.to_lowercase().contains(&query) {
result.push(line);
}
}
result
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn one_result() {
let query = "xwp";
let content = "\
Hello,rust!
xwp is handsome
You know!";
assert_eq!(vec!["xwp is handsome"], search(query, content));
}
#[test]
fn case_insensitive() {
let query = "xWp";
let content = "\
Hello,rust!
xwp is handsome
You KonW";
assert_eq!(vec!["xwp is handsome"], search_case_insensitive(query, content));
}
}
三、使用
- 需要输入两个参数,第一个是query,第二个是filename,如果参数少于两个会报错。
- 如:
cargo run xwp xwphs.txt
,xwp是要查询的内容,xwphs.txt是文件。 - minigrep默认是大小写敏感的,可通过设置
IGNORE_CASE
环境变量,使得查询忽略大小写。
在powershell中设置临时环境变量如:$Env:IGNORE_CASE=1
,解除:Remove-Item Env:IGNORE_CASE
;在shell中直接:将IGNORE_CASE=1放在最开始
参数不足时,提示Problem parse arguments: No enough argumentss
设置环境变量后,不区分大小写,查询到了信息
到此这篇关于Rust实现grep命令行工具的文章就介绍到这了,更多相关Rust命令行工具内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341