grep 和 Python
Posted
技术标签:
【中文标题】grep 和 Python【英文标题】:Grep and Python 【发布时间】:2010-12-27 16:07:47 【问题描述】:我需要一种通过 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
不会打印
【问题讨论】:
如果你真的想在 grep 中使用 python 风格的正则表达式,grep 的 --perl-regex 选项非常接近。它为您提供 perl 风格的正则表达式支持。 (另外,我最喜欢的 grep 未充分使用的选项是 --color=always ) 【参考方案1】:你可以使用 python-textops3 :
from textops import *
print('\n'.join(cat(f) | grep(search_term)))
使用 python-textops3,您可以使用带有管道的类 unix 命令
【讨论】:
【参考方案2】:简洁和高效的内存:
#!/usr/bin/env python
# file: grep.py
import re, sys
map(sys.stdout.write,(l for l in sys.stdin if re.search(sys.argv[1],l)))
它像 egrep 一样工作(没有太多的错误处理),例如:
cat input-file | grep.py "RE"
这里是单线:
cat input-file | python -c "import re,sys;map(sys.stdout.write,(l for l in sys.stdin if re.search(sys.argv[1],l)))" "RE"
【讨论】:
【参考方案3】:真正的问题是变量 line 总是有一个值。 “未找到匹配项”的测试是是否存在匹配项,因此代码“if line == None:”应替换为“else:”
【讨论】:
【参考方案4】:自然的问题是为什么不直接使用 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 shell 那样)。如果您想要此功能,您可以使用以下方法获得它:
import re
import sys
import glob
for arg in sys.argv[2:]:
for file in glob.iglob(arg):
for line in open(file, 'r'):
if re.search(sys.argv[1], line):
print line,
【讨论】:
你应该在使用循环之前编译你的正则表达式。 这有两个反对票,我不知道为什么。投反对票的人想发表评论吗?我知道您可以添加正则表达式编译等,但我认为这会降低答案的清晰度。我不认为有什么不正确的,我已经运行了代码,与其他一些答案不同 这个答案对我来说是完美的,谢谢。又一个小问题,如果没有找到匹配项,我将如何打印? “你应该在使用循环之前编译你的正则表达式。”,不,Python 会自己编译和缓存它,这是一个常见的神话,出于可读性的原因,这是一件好事,很难。 自然问题的合理答案是“因为代码是更大的 Python 脚本的一部分,在这种情况下谁愿意调用 grep?”简而言之,我很高兴这个问题在这里,因为我正在用 Python 脚本替换 bash 脚本,希望在系统上更容易。【参考方案5】:改编自grep in python。
通过[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]
resp sys.argv[2:]
有效,如果您将其作为独立的可执行文件运行,则意味着
chmod +x
第一
【讨论】:
re.match
和re.search
有什么区别?
@OscarRyz 请参阅Nick Fortescue's top answer: "search
而不是match
以查找字符串中的任何位置"【参考方案6】:
您可能对pyp 感兴趣。引用我的另一个answer:
“The Pyed Piper”,或 pyp,是一个 linux 命令行文本操作 类似于 awk 或 sed 的工具,但它使用标准 python 字符串和 列表方法以及自定义函数演变为快速生成 导致紧张的生产环境。
【讨论】:
【参考方案7】:-
使用
sys.argv
获取命令行参数
使用open()
、read()
来操作文件
使用Python re module 匹配行
【讨论】:
以上是关于grep 和 Python的主要内容,如果未能解决你的问题,请参考以下文章