我一直在使用以下命令来grep我当前目录中和下面的所有python源文件中的字符串:
find . -name '*.py' -exec grep -nHr <string> {} \;
Run Code Online (Sandbox Code Playgroud)
我想简化一些事情,这样我就可以输入类似的内容
findpy <string>
Run Code Online (Sandbox Code Playgroud)
并获得完全相同的结果.别名似乎不够,因为它们只进行字符串扩展,而我需要指定的参数不是最后一个参数.听起来函数适合于任务,所以我有几个问题:
Gor*_*son 10
如果您不想为此创建整个脚本,则只需使用shell函数即可:
findpy() { find . -name '*.py' -exec grep -nHr "$1" {} \; ; }
Run Code Online (Sandbox Code Playgroud)
...但是你可能必须在〜/ .bashrc和〜/ .bash_profile中定义它,因此它为登录和交互式shell定义(参见bash手册页的INVOCATION部分).
上面的所有"find ... -exec"解决方案在它们工作的意义上都是可以的,但是它们非常低效,对于大树来说会非常慢.原因是他们为每个*.py文件启动了一个新进程.相反,使用xargs(1),并仅对文件(而不是目录)运行grep:
#! /bin/sh find . -name \*.py -type f | xargs grep -nHr "$1"
例如:
$ time sh -c 'find . -name \*.cpp -type f -exec grep foo {} \; >/dev/null'
real 0m3.747s
$ time sh -c 'find . -name \*.cpp -type f | xargs grep foo >/dev/null'
real 0m0.278s
另外,你应该看看Ack你正在做什么.它被设计为Perl编写的Grep的替代品.根据目标语言过滤文件或忽略.svn目录等.
示例(来自Trac源代码段):
$ ack --python foo ./mysource
ticket/tests/wikisyntax.py
139:milestone:foo
144:<a class="missing milestone" href="/milestone/foo" rel="nofollow">milestone:foo</a>
ticket/tests/conversion.py
34: ticket['foo'] = 'This is a custom field'
ticket/query.py
239: count_sql = 'SELECT COUNT(*) FROM (' + sql + ') AS foo'
Run Code Online (Sandbox Code Playgroud)