分享

用python编写一个高效搜索代码工具

 芯文苑eecourse 2019-01-16

大多码农在linux环境下使用grep+关键词的命令搜索自己想要的代码或者log文件。今天介绍用python如何编写一个更强大的搜索工具,windows下也适用。我们的需求:

1, 可以同时指定多个关键词。比如某个文件某一行中有”error: aa bb cc”,如果检索关键词errorcc则可以显示该行,避免单一关键词冗余信息太多

2, 可以排除某些关键词。对于”error: aa bb cc” ,如果设定排除bb,则不予显示该行

3, 可以指定某些文件名或者文件名后缀,如只搜索 .cpp.h 的文件

4, 可以排除某些文件名或者后缀,比如排除 .log .bak

5, 最重要一点,和grep一样,必须能够递归查找,只要指定一个目录,则自动逐层搜索该目录下所有的子文件夹,文件

6, 最后能打印出吻合的文件完整路径,能显示搜索到的行号

 

为了实现以上功能,我们需要用到python自带的os库函数,功能强大,先把用到的几个先做简单说明:

os.path.exists ( xxx ) 判断路径xxx是否存在

os.listdir ( xxx ) xxx路径下所有文件和文件夹名字转换成一个list列表

os.path.join ( aaa, bbb ) 把字符串aaabbb拼接成一个完整的文件绝对路径

os.path.isfile (xxx) 判断xxx是不是一个文件

os.path.isdir (xxx) 判断xxx是不是一个文件夹

 

以下是代码正文

# -*- coding: cp936 -*-

#代码准备工作

#由于需要获得文件的路径,所以要加载  ossystem

import os  

import sys

 

#设定两个检索关键词keyword errorcc

keyword1 = 'error'

keyword2 = 'cc'

 

#设定一个排除的exclude_word bb

exclude_word = 'bb'

 

#设定一组指定的文件名,使用list结构以便动态扩展

file_name_list = [ '.sv', '.v', '.cpp', '.h']

 

#设定不参与检索的文件名,也使用list结构

exclude_file_name_list = [ '.bak ' ]

 

#指定一个search_path路径,把字符串留空,只初始化,为了实现在konsole界面实时捕捉当前路径

search_path = ' '

 

#准备工作完毕

 

 

#下面创建一个my_search函数,目的是为了实现递归查找子文件夹

#如果只需要查找当前目录层次的文件,则可以不使用函数

#传入参数为当前路径,为了实现递归查找子文件夹

def  my_search ( search_path ):

   

    #防错机制,判断当前路径是否存在

    if  os.path.exists( search_path ) :

       

        #获得路径下所有文件文件夹的名字,并for循环遍历

        for  my_filename  in  os.listdir ( search_path ):

           

            #把当前路径和文件名拼接成完整绝对路径

            full_filepath = os.path.join ( search_path,  my_filename )

           

            #判断拼接出的完整路径是文件还是文件夹

            if os.path.isfile (full_filepath):

               

                #如果是文件,则对file_name_list中期望的文件名进行遍历

                for my_extend in file_name_list :

 

                    #判断.cpp .sv等在文件名中

                    if my_extend in my_filename :

                        flag = True

 

                        #exclude_file_name_list中不希望的文件名进行遍历

                        for my_exclude in exclude_file_name_list :

                            #若文件名有.bak就剔除

                            if my_exclude in my_filename:

                                flag =  False

 

                        if flag: #文件名匹配已经命中

                            i = 0 #i作为文件行号

 

                            #逐行读取文件,碰到特大文件就不会卡死程序

                            for line in open ( full_filepath ) :

                                i=i+1 #每次读一行,i+1

 

                                #判断关键字12(error, cc)在该行中,并且exclude_word(bb)不在该行

                                if (keyword1 in line) and (keyword2 in line) and (exclude_word not in line):

                                   

                                    #满足检索条件,打印文件完整路径,行号

                                    print full_filepath , 'line',i,':'

                                    print line #打印该行

 

 

            #当前完整路径不是文件,而是文件夹

            if os.path.isdir (full_filepath) :

               

                #执行函数递归,继续到下一层文件夹目录查找,直到底层文件

                my_search(full_filepath) 

 

    else : #防错机制,当前路径不存在,则报错

        print search_path, 'path not exist!'

 

 

 

 

#这里相当于C语言主函数,程序从这里开始执行

       

search_path = os.getcwd () #konsole获得当前路径,设为搜索路径

print search_path

my_search (search_path) #调用函数开始搜索

                                 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约