2-增强文本查找工具zgrip

1,932 阅读3分钟

背景

我们经常会使用 grep 命令, 奈何 grep 命令实在不怎么好用, 于是写一个python 脚本来包装 grep 命令,让它更友好一些,使用它可以极高的提高效率. 它可以让我们以更少的输入来快速完成原来很复杂的查询, 而且会打印出生成的底层语句, 来看几个例子吧.

例子

case1 简单初体验

以前我要使用 grep 查找当前目录下的"内容中包含XX的后缀是XX的文档", 而且希望它能忽略大小写, 能查找目录软链接下的内容, 我必须写很长的参数.
比如我之前想查找 当前目录下,名称中含有 make 的markdown 文件, 那么我必须写成: find . -name "*.md" | xargs grep "make" 作为对比, 我现在只用写: zgrip make 它会替我们生成语句: find -L . -name "*.md" | xargs grep make

case2 指定特定文件后缀查询

再比如, 我想找 当前目录下,名称中含有 make 的 md 文件, 那么我必须写成 find -L . -name "*.md" -print | awk '{a="\"";print a $0 a}' | xargs grep make -i -n -B2 -A2 作为对比, 我现在只用写: zgrip make -s md

case3 排除特定路径

有的时候,我不想找某个路径, 那么我可以使用 -e 来排除这个路径, e 是 exclude 的首字母. 它强制是模糊查询的. 我写这么一条语句: zgrip find -e blog 其实它会生成这么复杂的一条语句.
find -L . -name "*.md" -print -o -path "*blog*" -prune | awk '{a="\"";print a $0 a}' | xargs grep make -i -n -B2 -A2

使用

我将提供下面一段脚本, 只要你:

  1. 将它命令为 zgrip, 不要带.py后缀, 使用 chmod a+x zgrip 成为可执行文件
  2. 把它放到可执行文件的查找路径下
  3. 使用 zgrip 关键字 就可以愉快地使用了 因为我喜欢使用markdown 来写文档, 所以我默认让 find 命令查找 markdown 文件

脚本展示

第一行的 shebang 命令需要大家指定自己的 Python3 路径放在哪.

#! /usr/bin/env python3
#coding=utf-8
import os,sys


help_txt = """
使用 zgrip -h 来获取帮助
使用 zgrip 关键字 在当前目录查询含有`关键字`的md文档
使用 zgrip 关键字 -d 路径 在指定目录查询含有`关键字`的md文档
使用 zgrip 关键字 -d 路径 -s 文件后缀 在指定目录查询含有`关键字`的指定后缀文档
使用 zgrip 关键字 -e 排除路径  查询的时候排除指定路径
"""

######################## 准备变量
search_dir = ''
keyword = ''
suffix = 'NONE'
count = ''
exclude = ''

args = sys.argv
if len(args) > 1 and args[1] == '-h':
    print(help_txt)
if len(args) >= 2:
    keyword = sys.argv[1]

# 捕捉多余可选参数
opt_args = args[2:]
for i in range(len(opt_args)):
    if(opt_args[i] == '-s'):
        suffix = opt_args[i+1]
    if (opt_args[i] == '-d'):
        search_dir = opt_args[i+1]
    if (opt_args[i] == '-c'):
        count = opt_args[i+1]
    if (opt_args[i] == '-e'):
        exclude = opt_args[i+1]

######### 执行命令
search_dir = search_dir or '.'
if '+' in suffix:
    suffixes = suffix.split('+')
    # suffix = '.'+ suffix
    suffixes = list(set(suffixes))  # 去重
    suffixes = [item for item in suffixes]
    suffix = suffixes
else:
    suffix = '.md' if suffix=='NONE' else suffix

count = count or '2'
# 如果 -e 参数代表的 exclude 不为空,那么拼接上查询
exclude_phrase = '-o -path "*{}*" -prune'.format(exclude) if exclude else ''


def islist(a):
    from typing import List
    return isinstance(a, List)

def make_comand():
    command = []
    if islist(suffix):
        for suffix_part in suffix:
            command_part = 'find -L %s -name "*%s" -print %s | awk \'{a="\\"";print a $0 a}\' | xargs grep "%s" -i -n -B%s -A%s'%(search_dir, suffix_part, exclude_phrase, keyword, count, count)
            command.append(command_part)
    else:
        command = 'find -L %s -name "*%s" -print %s | awk \'{a="\\"";print a $0 a}\' | xargs grep "%s" -i -n -B%s -A%s'%(search_dir, suffix, exclude_phrase, keyword, count, count)
    # example as: find . -iname "*@make*.md"
    ######### 执行查询软链接命令
    return command

def exec_command(command):
    if islist(command):
        ret = []
        for command_part in command:
            print("the command is: ", command_part)
            ret_part = os.popen(command_part).readlines()
            ret.extend(ret_part)
    else:
        print("the command is: ", command)
        ret = os.popen(command).readlines()
    return ret

def main():
    command = make_comand()
    ret = exec_command(command)
    for line in ret:
        print(line, end='')

if __name__ == '__main__':
    main()








缺点

目前还没有发现

待做

我可以把它打包成一个 pip包, 大家可以直接使用 pip 安装就可以了.