終端搜索工具

做人嘛低散,開(kāi)心就好了

為了避免遺忘,先附上repo鏈接骡楼,有興趣的拿去用咯熔号。

https://github.com/guoruibiao/worktools/tree/master/searcher

前言

平時(shí)都是在終端下進(jìn)行開(kāi)發(fā),文件少代碼量不大的時(shí)候鸟整,查找某些方法也好引镊,關(guān)鍵字也罷,都還可以篮条,不算費(fèi)時(shí)弟头。但是隨著代碼量的不斷增加,項(xiàng)目越寫越大涉茧,很多文件赴恨,方法就根本找不到到底在哪個(gè)地方了。這個(gè)時(shí)候再去一個(gè)一個(gè)的找的話降瞳,就不好玩了嘱支。

也許你會(huì)說(shuō),我有IDE挣饥,全局搜索下不就好了除师,干嘛這么費(fèi)事咧。是的扔枫,IDE有其獨(dú)特的優(yōu)點(diǎn)汛聚。但是完全在終端下工作,就用不了純粹的IDE了短荐。VIM中有一個(gè)插件倚舀,叫ctrlp。在normal模式下按下Ctrl+P鍵忍宋,就可以查找本級(jí)目錄(以及子目錄)下包含有輸入的關(guān)鍵字的文件了痕貌。如下圖。


VIM插件Ctrlp的文件查詢效果

相信你也能看出來(lái)了糠排,ctrlp能找到的只是一個(gè)文件名舵稠,對(duì)于內(nèi)部的變量還是心有余而力不足的。當(dāng)然了,在VIM中其實(shí)也不是個(gè)事哺徊。各種插件工具室琢,搞一搞,不輸IDE落追。但是這和今天要寫的工具的預(yù)期有點(diǎn)差距盈滴。我們要找到某個(gè)目錄下包含某個(gè)方法,某個(gè)關(guān)鍵字的具體的位置轿钠。

在正式開(kāi)始制作工具之前巢钓,下面需要先熟悉一下一些基礎(chǔ)的東西。

查找

查找谣膳,基本上分為兩塊竿报。一個(gè)是查找文件,一個(gè)是查找內(nèi)容继谚。

文件查找

最常用的文件查找命令是find烈菌。

find path -name "regex "
# 示例
?  worktools git:(master) ? find ./ -name "*.p*"
.//searcher/colorcmd.pyc
.//searcher/searcher.py
.//searcher/colorcmd.py
.//sqlhelper/sqlhelper.py
.//sqlhelper/datatransfer.py
.//dingding/dingding.py
.//interfacetool.py
.//getrealip.py
.//detect-actions.py
.//getall/finder.py
.//getall/get.py
.//redis-analyzer/server.py
.//redis-analyzer/redishelper.py
.//redis-analyzer/__init__.py
.//redis-analyzer/__pycache__/redishelper.cpython-36.pyc
.//redis-analyzer/temp.py

可以看出find還會(huì)幫我們進(jìn)行遞歸式的查找。

內(nèi)容查找

實(shí)現(xiàn)內(nèi)容查找的方式有很多方式花履,使用grep命令芽世,或者使用Perl,Python诡壁,shell等腳本語(yǔ)言來(lái)做處理都是可以的济瓢。當(dāng)然,不同的方式實(shí)現(xiàn)的最終效果也會(huì)有差距妹卿。

如果只是簡(jiǎn)單的想知道哪個(gè)文件包含了目標(biāo)關(guān)鍵字旺矾,使用grep就可以了。

?  worktools git:(master) ? grep 遞歸 searcher/searcher.py 
        # 明天做下遞歸版本
?  worktools git:(master) ? 

但是如果想知道包含了關(guān)鍵字在(多個(gè))文件中的行數(shù)夺克,位置箕宙,這個(gè)時(shí)候在使用grep等命令就有點(diǎn)捉襟見(jiàn)肘了。但也不是說(shuō)不能實(shí)現(xiàn)铺纽,如:

?  worktools git:(master) ? find ./ -name "*.p*" | xargs grep 遞歸
.//searcher/searcher.py:        # 明天做下遞歸版本
?  worktools git:(master) ? find ./ -name "*.p*" | xargs grep hello
.//interfacetool.py:#cmd = "wget http://fanyi.badu.com/v2transapi?query=hello | python -m json.tool"
?  worktools git:(master) ? find ./ -name "*.p*" | xargs grep coding
Binary file .//searcher/colorcmd.pyc matches
.//searcher/searcher.py:#coding: utf8
.//searcher/searcher.py:sys.setdefaultencoding("utf8")
.//searcher/colorcmd.py:# coding: utf8
.//searcher/colorcmd.py:sys.setdefaultencoding("utf8")
.//sqlhelper/sqlhelper.py:# coding: utf8
.//sqlhelper/datatransfer.py:# coding: utf8
.//sqlhelper/datatransfer.py:sys.setdefaultencoding('utf8')
.//dingding/dingding.py:# coding: utf8
.//interfacetool.py:# coding: utf8
.//getrealip.py:# coding: utf8
.//detect-actions.py:# coding: utf8
.//getall/finder.py:# coding: utf8
.//getall/get.py:# coding: utf8
.//redis-analyzer/server.py:# coding: utf8
.//redis-analyzer/server.py:sys.setdefaultencoding('utf8')
.//redis-analyzer/redishelper.py:# coding: utf8
.//redis-analyzer/__init__.py:# coding: utf8
.//redis-analyzer/temp.py:# coding: utf8
?  worktools git:(master) ? 

而使用一些稍微高級(jí)一點(diǎn)的腳本語(yǔ)言柬帕,能實(shí)現(xiàn)的功能就會(huì)更多樣化。比如高亮顯示查找的關(guān)鍵字狡门,添加行號(hào)元數(shù)據(jù)等等陷寝,這些使用高級(jí)語(yǔ)言,會(huì)更方便一點(diǎn)其馏。

高亮工具

大二的時(shí)候接觸的Python凤跑,一開(kāi)始也是在命令行里面不斷摸索這,從理解命令行參數(shù)的使用到自己封裝了一個(gè)getpass2的庫(kù)叛复。什么進(jìn)度條啊的都算是玩了下饶火。在這么多的庫(kù)中鹏控,有一個(gè)讓我確實(shí)印象深刻。那就是colorama肤寝。一個(gè)可以讓非黑即白的終端瞬間變得多姿多彩起來(lái)。

對(duì)我而言抖僵,colorama足夠好用鲤看,但是init(autoreset=True)有時(shí)候并不能滿足我的需求。比如我只想高亮某個(gè)關(guān)鍵字耍群,需要操作的那就太多了义桂。于是我打算自己寫一個(gè)類似的,滿足我的需求就好了蹈垢,于是有了colorcmd慷吊。在正式寫代碼之前,還是要先理解下如何讓終端輸出多種顏色曹抬。

知識(shí)點(diǎn)普及

在支持真彩色的終端中溉瓶,有這么一個(gè)約定。

ESC鍵的轉(zhuǎn)移序列為ASCII碼的\033.
變換顏色的格式如下:

\033[顯示方式;前景色;背景色m

需要注意的是:顯示方式谤民,前景色堰酿,背景色至少存在一個(gè)就可以。如果存在多個(gè)张足,記得使用英文的分號(hào)進(jìn)行分割触创。

顯示方式有如下取值:

  • 0 關(guān)閉所有效果
  • 1 高亮
  • 4 下劃線
  • 5 閃爍
  • 7 反色
  • 8 不可見(jiàn)
顯示方式特效

前景色以3開(kāi)頭,背景色以4開(kāi)頭为牍。緊鄰的為顏色取值哼绑,分別為:

  • 0 黑色
  • 1 紅色
  • 2 綠色
  • 3 黃色
  • 4 藍(lán)色
  • 5 紫色
  • 6 青色
  • 7 白色

簡(jiǎn)單的來(lái)測(cè)試下。


字體顏色特征

工具編寫

這里我打算使用shell配合Python實(shí)現(xiàn)一個(gè)關(guān)鍵字高亮搜索的小工具碉咆。具體會(huì)有如下文件:

colorcmd.py 終端顏色樣式工具類
searcher.py 關(guān)鍵字搜索
searcher.sh 文件搜索

searcher.sh

#!/usr/bin bash
# 使用shell配合Python腳本查找文件中某一個(gè)變量或者字符串所在的行數(shù)


filelist=`find $1 -name "*.*"`

for file in ${filelist[@]};do
    #echo $file;
    python /Users/changba164/guo/tools/worktools-master/worktools/searcher/searcher.py $file $2
done;

#find $1 -name "*.*" | xargs python $2

searcher.py

#!/usr/bin python
#coding: utf8
import sys
reload(sys)
sys.setdefaultencoding("utf8")
import re
import os
from colorcmd import Color, Style, Enhancer


def find(filepath, keyword):
    if os.path.isdir(filepath):
        # 明天做下遞歸版本
        return []
    result = []
    with open(filepath, 'r') as file:
        lines = file.readlines()
        file.close()
        # 遍歷每一行抖韩,讀取包含關(guān)鍵字的行,并進(jìn)行臨時(shí)存儲(chǔ)吟逝,用于后續(xù)美化輸出
    counter = 0
    for line in lines:
        counter += 1
        if keyword.lower() in line.lower():
            wrappedword = Enhancer.mix(keyword, Color.BLACK_DEEPGREEN, Style.HIGHLIGHT+Style.UNDERLINE+Style.BLINK)
            tmp = {"number": counter, "line":line.rstrip("\n").replace(keyword, wrappedword)}
            result.append(tmp)
    return result

def pretty_print(filepath, rows):
    for row in rows:
        if row is not None or row != []:
            print "-------"*5 + filepath + "-------"*5
            print "Line: {}\t {}".format(row['number'], row['line'])
filepath = sys.argv[1]
keyword = sys.argv[2]
rows = find(filepath, keyword)
pretty_print(filepath, rows)

colorcmd.py

#!/usr/bin python
# coding: utf8
import sys
reload(sys)
sys.setdefaultencoding("utf8")
"""
# 之前用過(guò)一個(gè)colorama的庫(kù)帽蝶,挺好用的,但是有一個(gè)缺點(diǎn)就是有時(shí)候init(autoreset=True)并不很好使块攒,究其原因励稳,還是設(shè)計(jì)層面的問(wèn)題
于是我打算使用“包裝”的思想,來(lái)做一個(gè)更好用一點(diǎn)的出來(lái)囱井。
"""

class Color(object):
    CLEAR = "\33[0m"
    # 字體顏色 前景色
    FORE_BLACK = "\33[30m"
    FORE_RED = "\33[31m"
    FORE_GREEN = "\33[32m"
    FORE_YELLOW = "\33[33m"
    FORE_BLUE = "\33[34m"
    FORE_PURPLE = "\33[35m"
    FORE_DEEPGREEN = "\33[36m"
    FORE_WHITE = "\33[37m"
    # 背景色
    BACK_BLACK = "\33[40"
    BACK_RED = BACK_DEEPRED = "\33[41m"
    BACK_GREEN = "\33[42m"
    BACK_YELLOW = "\33[43m"
    BACK_BLUE = "\33[44m"
    BACK_PURPLE = "\33[45m"
    BACK_DEEPGREEN = "\33[46m"
    BACK_WHITE = "\33[47m"
    # 黑底彩色
    BLACK_BLACK = "\33[90m"
    BLACK_RED = BLACK_DEEPRED = "\33[91m"
    BLACK_GREEN = "\33[92m"
    BLACK_YELLOW = "\33[93m"
    BLACK_BLUE = "\33[94m"
    BLACK_PURPLE = "\33[95m"
    BLACK_DEEPGREEN = "\33[96m"
    BLACK_WHITE = "\33[97m"
    """
    顏色相關(guān)工具類
    """
    def __init__(self):
        pass


class Style(object):
    CLEAR = "\33[0m"
    HIGHLIGHT = "\33[1m"
    UNDERLINE = "\33[4m"
    BLINK = "\33[5m"
    REVERSE = "\33[7m"
    BLANKING = "\33[8m"
    """
    樣式相關(guān)驹尼,前景色,背景色,加粗庞呕,下劃線等
    """
    def __init(self):
        pass

class Enhancer(object):
    """
    曾經(jīng)有一個(gè)tag的交叉疊加新翎,給了我這個(gè)思路程帕。目標(biāo)是做成一個(gè)無(wú)限疊加的增強(qiáng)品。
    """
    def __init__(self):
        pass

    @staticmethod
    def highlight(text="", color=Color.FORE_RED, style=Style.CLEAR):
        return Style.HIGHLIGHT + style + color + text + Style.CLEAR

    @staticmethod
    def mix(text, color=Color.CLEAR, style=Style.CLEAR, highlight=False):
        return style + color + text + Style.CLEAR
if __name__ == "__main__":
    #print "\33[5m"+Color.FORE_GREEN+"Hello World!"+"\33[0m"
    text = "郭璞"
    print Enhancer.highlight(text, Color.BACK_GREEN, Style.BLINK)
    print Enhancer.mix("what a amazing colorama!", Color.BLACK_PURPLE, Style.UNDERLINE+Style.HIGHLIGHT+Style.BLINK)


代碼比較簡(jiǎn)單地啰,但是還是有很大的拓展空間的愁拭。

  • 比如以多線程的形式進(jìn)行查找,這樣速度會(huì)更加迅速亏吝。

  • 終端輸出的美化效果岭埠,現(xiàn)在就是個(gè)簡(jiǎn)單的輸出了,如果有必要的話蔚鸥,可以借助PrettyTable這個(gè)庫(kù)實(shí)現(xiàn)更優(yōu)雅的輸出效果惜论。

如何使用

這個(gè)工具的入口是searcher.sh,所以正常使用的話可以這么干:

sh ./searcher.sh targetpath keyword
# 示例
?  searcher git:(master) ? sh searcher.sh ./ default
---------.//searcher.py------------
Line: 5  sys.setdefaultencoding("utf8")
---------.//colorcmd.py------------
Line: 5  sys.setdefaultencoding("utf8")
?  searcher git:(master) ? 

但是這樣每次都要輸入一下sh命令 挺麻煩的。因此止喷,放到alias里面就好多了馆类。

vim ~/.zshrc (我的Mac安裝了zsh,所以這里是~/.zshrc, 如果你用的是Linux弹谁,那么應(yīng)該是~/.bashrc. 沒(méi)有的話就新建一個(gè)乾巧。)
# 在最后面加上這么一行命令。
alias search='sh /absolute path/searcher.sh'
# 保存退出后還差一句命令,讓別名的配置可以在當(dāng)前的會(huì)話終端內(nèi)生效僵闯。
source ~/.zshrc

完成后就可以很方便的在終端內(nèi)搜索了卧抗。
格式如下:

search path keyword
做人嘛,開(kāi)心就好了
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末鳖粟,一起剝皮案震驚了整個(gè)濱河市社裆,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌向图,老刑警劉巖泳秀,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異榄攀,居然都是意外死亡嗜傅,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門檩赢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)吕嘀,“玉大人,你說(shuō)我怎么就攤上這事贞瞒∨挤浚” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵军浆,是天一觀的道長(zhǎng)棕洋。 經(jīng)常有香客問(wèn)我,道長(zhǎng)乒融,這世上最難降的妖魔是什么掰盘? 我笑而不...
    開(kāi)封第一講書人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任摄悯,我火速辦了婚禮,結(jié)果婚禮上愧捕,老公的妹妹穿的比我還像新娘奢驯。我一直安慰自己,他們只是感情好晃财,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布叨橱。 她就那樣靜靜地躺著,像睡著了一般断盛。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上愉舔,一...
    開(kāi)封第一講書人閱讀 49,111評(píng)論 1 285
  • 那天钢猛,我揣著相機(jī)與錄音,去河邊找鬼轩缤。 笑死命迈,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的火的。 我是一名探鬼主播壶愤,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼馏鹤!你這毒婦竟也來(lái)了征椒?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤湃累,失蹤者是張志新(化名)和其女友劉穎勃救,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體治力,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蒙秒,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了宵统。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片晕讲。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖马澈,靈堂內(nèi)的尸體忽然破棺而出瓢省,到底是詐尸還是另有隱情,我是刑警寧澤箭券,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布净捅,位于F島的核電站,受9級(jí)特大地震影響辩块,放射性物質(zhì)發(fā)生泄漏蛔六。R本人自食惡果不足惜荆永,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望国章。 院中可真熱鬧具钥,春花似錦、人聲如沸液兽。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)四啰。三九已至宁玫,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間柑晒,已是汗流浹背欧瘪。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留匙赞,地道東北人佛掖。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像涌庭,于是被迫代替她去往敵國(guó)和親芥被。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • Ubuntu的發(fā)音 Ubuntu羹铅,源于非洲祖魯人和科薩人的語(yǔ)言,發(fā)作 oo-boon-too 的音愉昆。了解發(fā)音是有意...
    螢火蟲de夢(mèng)閱讀 99,159評(píng)論 9 467
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,519評(píng)論 25 707
  • linux資料總章2.1 1.0寫的不好抱歉 但是2.0已經(jīng)改了很多 但是錯(cuò)誤還是無(wú)法避免 以后資料會(huì)慢慢更新 大...
    數(shù)據(jù)革命閱讀 12,135評(píng)論 2 34
  • 【手寫愛(ài)情繪本8.0】行走在紅塵里职员,每個(gè)人都會(huì)遇見(jiàn)暴風(fēng)驟雨和詩(shī)情畫意。當(dāng)歲月的帷幕徐徐拉開(kāi)跛溉,俗世中的每個(gè)人都成了人...
    主播亞?wèn)|閱讀 217評(píng)論 0 1
  • 行動(dòng)的意義不是為了別人的認(rèn)可焊切,而是你獲得了什么。 今天芳室,行動(dòng)營(yíng)結(jié)營(yíng)了专肪,我除了做到了全勤,其他什么都沒(méi)有堪侯。如果說(shuō)沒(méi)有...
    成長(zhǎng)的溫度閱讀 552評(píng)論 0 2