在指定目录下的文件中搜索字符串

在指定目录下的文件中搜索字符串

程序参数为: search [dir] [regex]
例如:

search document “^#” : 在 ./document 目录下的所有文件中查找符合正则表达式 ^# 的文件

代码比较简单,使用了线程池以加速搜索

import logging
import os
import re
import sys
from concurrent.futures.thread import ThreadPoolExecutor

import chardet

# main.py dir str
# regex support

# 创建线程池
exector = ThreadPoolExecutor()


def is_binary_file(file_path: str):
    binary_array = (
        'png', 'jpg', 'ico', 'icns'                         # 图片
        , 'woff2', 'ttf', 'otf'                             # 字体
        , 'zip', '7z', 'rar', 'gz', 'xz', 'tar'             # 压缩文件
        , 'mp3', 'wav', 'ape', 'flac'                       # 音乐文件
        , 'mp4', 'avi', 'flv'                               # 音频文件
        , 'docx', 'doc', 'xlsx', 'xls', 'pdf'               # 文档
        , 'obj', 'exe', 'idx', 'bin', 'lib', 'a', 'dll'     # 其他二进制文件
        , 'dat', 'iso', 'assets', 'resource', 'pack', 'pak'
    )
    logging.debug(file_path.split('.')[-1])
    if file_path.split('.')[-1] in binary_array:
        return True
    return False


def search_in_file(file_path: str):
    # 检测文件编码
    data: bytes = bytes(10)
    with open(file_path, 'rb') as f:
        data = f.read()
    encoding_result = chardet.detect(data)
    # 搜索文件
    try:
        file_content: str = data.decode(encoding_result['encoding'])
        result = re.search(sys.argv[2], file_content)
        if result is not None:
            print(file_path)
    except Exception:
        logging.error("%s 查看失败", file_path)


def search_from_dir() -> None:
    dir_name = os.path.join(os.getcwd(), sys.argv[1])
    for dirpath, dirnames, filenames in os.walk(dir_name):
        for file_name in filenames:
            file_path = os.path.join(dirpath, file_name)

            # 判断是否是二进制文件
            if is_binary_file(file_path):
                continue
            # 若文件太大就跳过
            file_size = int(os.stat(file_path).st_size/1024/1024)  # 单位为 MB
            if file_size > 8:
                logging.warning("文件 %s 由于尺寸过大而被跳过", file_path)
                continue
            # 将任务提交给线程池
            exector.submit(search_in_file, file_path)


if __name__ == "__main__":
    logging.basicConfig(level=logging.WARNING)
    if len(sys.argv) != 3:
        sys.exit(-1)
    search_from_dir()
    # 关闭线程池
    exector.shutdown(wait=True)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值