Rust實現(xiàn)grep命令行工具的方法
一、功能:
1、輸入要查詢的字符串和文件名,輸出所有匹配的行的內(nèi)容
2、如果設(shè)置環(huán)境變量IGNORE_CASE,則grep匹配將忽略大小寫
3、可使用 > 符號來重定向標(biāo)準(zhǔn)輸出到指定文件中
二、介紹
2.1 使用到的知識:
- 讀取命令行參數(shù)
- 讀取文件內(nèi)容
- 錯誤處理
- Test Driven Development(TDD)
- 使用環(huán)境變量控制不同行為
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));
}
}
三、使用
- 需要輸入兩個參數(shù),第一個是query,第二個是filename,如果參數(shù)少于兩個會報錯。
- 如:
cargo run xwp xwphs.txt,xwp是要查詢的內(nèi)容,xwphs.txt是文件。 - minigrep默認(rèn)是大小寫敏感的,可通過設(shè)置
IGNORE_CASE環(huán)境變量,使得查詢忽略大小寫。
在powershell中設(shè)置臨時環(huán)境變量如:$Env:IGNORE_CASE=1,解除:Remove-Item Env:IGNORE_CASE;在shell中直接:將IGNORE_CASE=1放在最開始
參數(shù)不足時,提示Problem parse arguments: No enough argumentss

設(shè)置環(huán)境變量后,不區(qū)分大小寫,查詢到了信息

到此這篇關(guān)于Rust實現(xiàn)grep命令行工具的文章就介紹到這了,更多相關(guān)Rust命令行工具內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解Rust編程中的共享狀態(tài)并發(fā)執(zhí)行
雖然消息傳遞是一個很好的處理并發(fā)的方式,但并不是唯一一個,另一種方式是讓多個線程擁有相同的共享數(shù)據(jù),本文給大家介紹Rust編程中的共享狀態(tài)并發(fā)執(zhí)行,感興趣的朋友一起看看吧2023-11-11
Rust個人學(xué)習(xí)小結(jié)之Rust的循環(huán)
這篇文章主要介紹了Rust個人學(xué)習(xí)小結(jié)之Rust的循環(huán),今天主要了解了Rust語言的3種循環(huán)方法:?loop、while、for,本文結(jié)合實例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-01-01
rust多個mod文件引用和文件夾mod使用注意事項小結(jié)
在 Rust 項目中,可以使用 mod 關(guān)鍵字將一個文件夾或一個 rs 文件作為一個模塊引入到當(dāng)前文件中,本文給大家介紹rust多個mod文件引用和文件夾mod使用注意事項小結(jié),感興趣的朋友跟隨小編一起看看吧2024-03-03

