Grep与Python
我需要一种方法,可以通过Unix命令行使用grep来搜索文件,使用正则表达式。例如,当我在命令行输入:
python pythonfile.py 'RE' 'file-to-be-searched'
我希望在文件中搜索正则表达式 'RE'
,并打印出匹配的行。
这是我写的代码:
import re
import sys
search_term = sys.argv[1]
f = sys.argv[2]
for line in open(f, 'r'):
if re.search(search_term, line):
print line,
if line == None:
print 'no matches found'
但是当我输入一个文件中没有的词时,no matches found
并没有打印出来。
8 个回答
9
这段内容改编自一个关于在Python中使用grep的教程。
它接受一个文件名的列表,通过 [2:]
来获取,但没有处理任何异常情况:
#!/usr/bin/env python
import re, sys, os
for f in filter(os.path.isfile, sys.argv[2:]):
for line in open(f).readlines():
if re.match(sys.argv[1], line):
print line
如果你把它当作独立的可执行文件来运行,使用 sys.argv[1]
和 sys.argv[2:]
是可以的,这意味着你需要先执行
chmod +x
来给文件添加执行权限。
13
简洁且节省内存:
#!/usr/bin/env python
# file: grep.py
import re, sys, collections
collections.deque(map(sys.stdout.write,(l for l in sys.stdin if re.search(sys.argv[1],l))),maxlen=0)
它的工作方式类似于 egrep(没有太多的错误处理),比如:
cat input-file | grep.py "RE"
这里是一个一行代码的写法:
cat input-file | python -c "import re,sys,collections;collections.deque(map(sys.stdout.write,(l for l in sys.stdin if re.search(sys.argv[1],l))),maxlen=0)" "RE"
注意,在 Python3 中需要使用 collections.deque
这个函数,因为 map 函数现在变得比较懒惰了。
97
大家可能会问,为什么不直接用grep呢?不过假设你不能用它……
import re
import sys
file = open(sys.argv[2], "r")
for line in file:
if re.search(sys.argv[1], line):
print line,
这里有几点需要注意:
- 用
search
而不是match
,这样可以在字符串的任何地方查找 - 在
print
后面加个逗号(,
)可以去掉换行符(这样这一行就不会换行了) argv
里包含了Python文件的名字,所以变量的索引要从1开始
这个方法不能处理多个参数(就像grep那样),也不能扩展通配符(就像Unix命令行那样)。如果你想要这些功能,可以用下面的代码:
#!/usr/bin/env python3
import re
import sys
import glob
regexp = re.compile(sys.argv[1])
for arg in sys.argv[2:]:
for fn in glob.iglob(arg):
with open(fn) as file:
for line in file:
if re.search(regexp, line):
print(line, end='')