巧用這幾種文本檢索工具,節(jié)省80%的時(shí)間!
說(shuō)到文本搜索工具,大家一定會(huì)想到 grep, 它是 Linux 最有用并最常用的工具之一。grep 在我們?nèi)粘5膶W(xué)習(xí)和工作中是必不可少的,但是,當(dāng)我們需要在一個(gè)比較大的工程項(xiàng)目中搜索某個(gè)關(guān)鍵詞時(shí),grep 的效率是比較低的。
對(duì)于所有的檢索工具來(lái)說(shuō),最重要的步驟永遠(yuǎn)是找出要搜索的內(nèi)容。而 grep 這個(gè)工具就比較質(zhì)樸,它只是在我們指定路徑的所有文件上搜索內(nèi)容,針對(duì) grep 這種情況,ack 就應(yīng)運(yùn)而生了。與 grep 不同,ack 默認(rèn)情況下不會(huì)搜索所有內(nèi)容,而是嘗試一種更加智能的方式來(lái)搜索。我們現(xiàn)在所用的大部分檢索工具都是從這兩個(gè)工具中派生出來(lái)的,比如 sift 就是由 grep 派生;ag、ucg 和 pt 由 ack 派生;而 ripgrep 混合了兩大派系,它有點(diǎn)像 grep 擅長(zhǎng)用來(lái)搜索大文件,又提供了像ack一樣的智能搜索。本文給大家介紹 grep、ag 和 rg 三款工具對(duì)比。
1. 安裝方式
· grep
優(yōu)麒麟各版本操作系統(tǒng)預(yù)裝了 grep 工具,不需要額外安裝。
· ripgrep
deb 包安裝:
curl -LO https://github.com/BurntSushi/ripgrep/releases/download/0.10.0/ripgrep_0.10.0_amd64.deb sudo dpkg -i ripgrep_0.10.0_amd64.deb
· silversearcher-ag
sudo apt install silversearcher-ag
2. 使用方法對(duì)比
以上三款工具使用的命令方式存在比較大的差別,但是在檢索中文字符串時(shí),默認(rèn)都只支持 UTF-8 格式的文件。
這里就不列舉選項(xiàng)參數(shù)了,如有需要可通過(guò) [命令] --help 查看。
· grep
grep [選項(xiàng)]... PATTERN [文件]...
支持正則表達(dá)式;功能多樣;可以更加精確、靈活地檢索出單詞;檢索范圍為指定目錄的所有類型的文件;不支持轉(zhuǎn)換編碼格式。
· silversearcher-ag
ag [文件類型] [選項(xiàng)] PATTERN [路徑]
支持正則表達(dá)式;檢索時(shí)會(huì)自動(dòng)忽略 .gitignore 文件和隱藏文件以加快檢索速度;默認(rèn)當(dāng)前工作目錄;默認(rèn)遞歸檢索;默認(rèn)顯示檢索字符串的位置;文件類型如果省略,ag 會(huì)檢索它支持的所有文件類型,并且 ag 不支持轉(zhuǎn)換編碼格式。
· ripgrep
rg [選項(xiàng)] PATTERN [路徑 ...] rg [選項(xiàng)] [-e PATTERN ...] [-f PATTERNFILE ...] [路徑...] rg [選項(xiàng)] --files [路徑...] rg [選項(xiàng)] --type-list command | rg [選項(xiàng)] PATTERN
默認(rèn)選項(xiàng)與 ag 類似。但是 rg 有 -E 選項(xiàng)可以指定其他編碼格式,ag 和 grep 都沒(méi)有此功能。在檢索中文內(nèi)容時(shí)這個(gè)功能很有用,但是用了-E選項(xiàng)轉(zhuǎn)換到其他編碼格式之后,將不支持原先的默認(rèn)格式,使用時(shí)需做出取舍。
使用方法上,grep 具有更好的靈活性,而 rg 和 ag 則更加地智能。它使用簡(jiǎn)單,可以幫助用戶處理掉了一些本來(lái)需要用戶自己處理的情況,不用記那么多繁雜的命令行參數(shù),但是也有人認(rèn)為 rg 和 ag 這種做法限制了其適用性。
3. 原理解析
· grep
使用了 Boyer-Moore 字符串檢索算法。對(duì)輸入進(jìn)行優(yōu)化,具體方法為使用系統(tǒng)調(diào)用,以避免數(shù)據(jù)拷貝帶來(lái)的開(kāi)銷,以及避免了對(duì)輸入進(jìn)行分行,直接將文本放在了 Buffer 中進(jìn)行處理,在找到了匹配的字符串之后,再去查找里面有沒(méi)有換行符,因?yàn)椴檎覔Q行符代價(jià)太大,需要逐字符查找。
· ag
ag 使用 pthreads 來(lái)利用多核并行搜索文件。文件使用內(nèi)存映射的方式,而不是讀入緩沖區(qū)。使用了 Boyer-Moore 字符串檢索算法,正則表達(dá)式搜索使用了 PCRE 的 JIT 編譯器( PCRE 版本大于 8.21 )。
· rg
基于 Rust 的 regex 引擎實(shí)現(xiàn)。Rust 的 regex 引擎使用 SIMD 和大量的文本優(yōu)化,使得搜索速度非???,還通過(guò)將 UTF-8 解碼直接構(gòu)建到引擎中,在完全支持 Unicode 的情況下保持性能。它支持使用內(nèi)存映射或中間緩沖區(qū)增量搜索,前者適用于單個(gè)文件,后者適用于大型目錄,并且會(huì)自動(dòng)選擇最佳搜索策略。
4. 性能對(duì)比分析
關(guān)于性能方面的對(duì)比,沒(méi)有比實(shí)際操作更有說(shuō)服力的了。同時(shí)為了保證檢索量足夠大,性能差異足夠明顯,下面我將在一份大型程序源碼中(源碼行數(shù)千萬(wàn)數(shù)量級(jí)),分別用三個(gè)命令搜索同一關(guān)鍵字,并顯示其搜索時(shí)間(測(cè)試環(huán)境為 8 核 16GB )。每個(gè)工具的具體運(yùn)行參數(shù)如下:
· grep
為保證單一變量,grep 參數(shù)設(shè)置為 Hrni ,與 ag 和 rg 的默認(rèn)選項(xiàng)保持一致。
time grep -Hrni “activity”
· silversearcher-ag
time ag -i “activity”
· ripgrep
time rg -i “activity”
| 工具\(yùn)時(shí)間 | real | user | sys |
| grep | 17m8.533s | 12m26.419s | 2m18.439s |
| ag | 3m26.340s | 2m10.055s | 1m5.888s |
| rg | 1m27.991s | 0m38.146s | 0m57.674s |
性能對(duì)比表
由此可見(jiàn),單論檢索速度,ripgrep > silversearcher-ag > grep,且 ripgrep 的性能遠(yuǎn)超其他兩個(gè)工具,同時(shí)這也證明了在這三款工具中 grep 的性能最低。ag 和 rg 之所以檢索速度這么快,除了默認(rèn)忽略一些文件類型之外,另一個(gè)很重要的原因在于它們都采用了多線程的方式,充分利用了多個(gè) CPU 內(nèi)核的性能。
5. END
從上文分析可以得知,rg 和 ag 無(wú)論是在使用上還是性能上,都要優(yōu)于 grep 。其中, rg 無(wú)疑是三個(gè)工具當(dāng)中最好的,大型項(xiàng)目中使用 rg 一定能事半功倍。當(dāng)然,也不是說(shuō) grep 就完全沒(méi)有用了,在一些特定的場(chǎng)景下,比如我們需要搜索所有文件,包括隱藏文件,那 grep 就可以大展拳腳了。大部分檢索場(chǎng)景還是更看重速度,此時(shí)最好使用 rg 或 ag 。
通訊員:鄧四云
來(lái) 源:終端研發(fā)部
審 核:優(yōu)麒麟社區(qū)