鍍金池/ 教程/ Java/ 目錄操作:簡單grep
標(biāo)準(zhǔn)輸入與輸出
消息傳遞
循環(huán)
注釋
Rust for Mac OS
幾種智能指針
Cell, RefCell
trait對象 (trait object)
rust web 開發(fā)
Unsafe、原始指針
Macro
迭代器
函數(shù)
Borrow, BorrowMut, ToOwned
快速上手
二叉樹
編輯器
測試與評測
Deref
安裝Rust
哈希表 HashMap
原生類型
17.錯誤處理
VS Code 安裝配置
動態(tài)數(shù)組Vec
模式匹配
操作符和格式化字符串
Rust for Linux
函數(shù)參數(shù)
Visual Studio
vim/GVim安裝配置
閉包作為參數(shù)和返回值
安全(Safety)
Cow
生命周期( Lifetime )
閉包的實現(xiàn)
所有權(quán)(Ownership)
Atom
將Rust編譯成庫
類型、運算符和字符串
類型系統(tǒng)中的幾個常見 trait
特性
屬性和編譯器參數(shù)
Spacemacs
集合類型
Rust json處理
Heap & Stack
并行
標(biāo)準(zhǔn)庫示例
基本程序結(jié)構(gòu)
鏈表
trait 和 trait對象
前期準(zhǔn)備
代碼風(fēng)格
編譯器參數(shù)
基于語義化版本的項目版本聲明與管理
Rust 版本管理工具: rustup
引用&借用(References&Borrowing)
注釋與文檔
10.1 trait關(guān)鍵字
模式
調(diào)用ffi函數(shù)
unsafe
并發(fā),并行,多線程編程
AsRef 和 AsMut
Rust旅程
Rust for Windows
結(jié)構(gòu)體與枚舉
條件分支
附錄I-術(shù)語表
變量綁定與原生類型
Mutex 與 RwLock
泛型
裸指針
常用數(shù)據(jù)結(jié)構(gòu)實現(xiàn)
系統(tǒng)命令:調(diào)用grep
Into/From 及其在 String 和 &str 互轉(zhuǎn)上的應(yīng)用
共享內(nèi)存
Sublime
網(wǎng)絡(luò)模塊:W貓的回音
函數(shù)返回值
包和模塊
高階函數(shù)
函數(shù)與方法
match關(guān)鍵字
隊列
目錄操作:簡單grep
語句和表達(dá)式
并發(fā)編程
閉包
測試
閉包的語法
同步
迭代器
String
Send 和 Sync
Rc 和 Arc
屬性
Emacs
優(yōu)先隊列
Prelude
cargo簡介
控制流(control flow)
數(shù)組、動態(tài)數(shù)組和字符串
FFI
模塊和包系統(tǒng)、Prelude
實戰(zhàn)篇
Rust 是一門系統(tǒng)級編程語言,被設(shè)計為保證內(nèi)存和線程安全,并防止段錯誤。作為系統(tǒng)級編程語言,它的基本理念是 “零開銷抽象”。理
運算符重載
Any和反射
rust數(shù)據(jù)庫操作
輸入輸出流
復(fù)合類型
性能測試

目錄操作:簡單grep

上一節(jié)我們實現(xiàn)了通過Command調(diào)用subprocess。這一節(jié),我們將通過自己的代碼去實現(xiàn)一個簡單的grep。當(dāng)然了,這種基礎(chǔ)的工具你是能找到源碼的,而我們的實現(xiàn)也并不像真正的grep那樣注重效率,本節(jié)的主要作用就在于演示標(biāo)準(zhǔn)庫API的使用。

首先,我們需要對當(dāng)前目錄進(jìn)行遞歸,遍歷,每當(dāng)查找到文件的時候,我們回調(diào)一個函數(shù)。

于是,我們就有了這么個函數(shù):

use std::env::args;
use std::io;
use std::fs::{self, File, DirEntry};
use std::path::Path;

fn visit_dirs(dir: &Path, pattern: &String, cb: &Fn(&DirEntry, &String)) -> io::Result<()> {
    if try!(fs::metadata(dir)).is_dir() {
        for entry in try!(fs::read_dir(dir)) {
            let entry = try!(entry);
            if try!(fs::metadata(entry.path())).is_dir() {
                try!(visit_dirs(&entry.path(), pattern, cb));
            } else {
                cb(&entry, pattern);
            }
        }
    }else{
        let entry = try!(try!(fs::read_dir(dir)).next().unwrap());
        cb(&entry, pattern);
    }
    Ok(())
}

我們有了這樣的一個函數(shù),有同學(xué)可能覺得這代碼眼熟。這不是標(biāo)準(zhǔn)庫里的例子改了一下么?

.

.

.

是啊!

好了,繼續(xù),我們需要讀取每個查到的文件,同時判斷每一行里有沒有所查找的內(nèi)容。 我們用一個BufferIO去讀取各個文件,同時用String的自帶方法來判斷內(nèi)容是否存在。

fn call_back(de: &DirEntry, pt: &String) {
    let mut f = File::open(de.path()).unwrap();
    let mut buf = io::BufReader::new(f);
    for line in io::BufRead::lines(buf) {
        let line = line.unwrap_or("".to_string());
        if line.contains(pt) {
            println!("{}", &line);
        }
    }
}

最后,我們將整個函數(shù)調(diào)用起來,如下:

use std::env::args;
use std::io;
use std::fs::{self, File, DirEntry};
use std::path::Path;

fn visit_dirs(dir: &Path, pattern: &String, cb: &Fn(&DirEntry, &String)) -> io::Result<()> {
    if try!(fs::metadata(dir)).is_dir() {
        for entry in try!(fs::read_dir(dir)) {
            let entry = try!(entry);
            if try!(fs::metadata(entry.path())).is_dir() {
                try!(visit_dirs(&entry.path(), pattern, cb));
            } else {
                cb(&entry, pattern);
            }
        }
    }else{
        let entry = try!(try!(fs::read_dir(dir)).next().unwrap());
        cb(&entry, pattern);
    }
    Ok(())
}

fn call_back(de: &DirEntry, pt: &String) {
    let mut f = File::open(de.path()).unwrap();
    let mut buf = io::BufReader::new(f);
    for line in io::BufRead::lines(buf) {
        let line = line.unwrap_or("".to_string());
        if line.contains(pt) {
            println!("{}", &line);
        }
    }
}

// 實現(xiàn)調(diào)用grep命令搜索文件
fn main() {
    let mut arg_iter = args();
    arg_iter.next();
    // panic if there is no one
    let pattern = arg_iter.next().unwrap_or("main".to_string());
    let pt =  arg_iter.next().unwrap_or("./".to_string());
    let pt = Path::new(&pt);
    visit_dirs(&pt, &pattern, &call_back).unwrap();
}

調(diào)用如下:

?  demo git:(master) ? ./target/debug/demo "fn main()" ../
fn main() {
fn main() { }
fn main() {
    pub fn main() {
    pub fn main() {}
fn main() {
    pub fn main() {
    pub fn main() {}