背景
我们经常会使用 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
使用
我将提供下面一段脚本, 只要你:
- 将它命令为 zgrip, 不要带
.py
后缀, 使用chmod a+x zgrip
成为可执行文件 - 把它放到可执行文件的查找路径下
- 使用 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 安装就可以了.