关于正则表达式:Grep和Python

Grep and Python

我需要一种通过unix命令行中的正则表达式使用grep搜索文件的方法。例如,当我输入命令行时:

1
python pythonfile.py 'RE' 'file-to-be-searched'

我需要在文件中搜索正则表达式'RE',并打印出匹配的行。

这是我的代码:

1
2
3
4
5
6
7
8
9
10
11
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?!但是假设你不能…

1
2
3
4
5
6
7
8
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在字符串中查找任何地方
  • 删除回车(行将有一个回车)后的逗号(,)
  • argv包含python文件名,因此变量需要从1开始

这不会处理多个参数(如grep)或扩展通配符(如unix shell)。如果需要此功能,可以使用以下方法获得:

1
2
3
4
5
6
7
8
9
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,


简洁和记忆效率:

1
2
3
4
5
#!/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(没有太多的错误处理),例如:

1
cat file-to-be-searched | grep.py"RE"

下面是一行:

1
cat file-to-be-searched | python -c"import re,sys;map(sys.stdout.write,(l for l in sys.stdin if re.search(sys.argv[1],l)))""RE"


改编自Python中的grep。

通过[2:]接受文件名列表,无异常处理:

1
2
3
4
5
6
7
#!/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

第一


  • 使用sys.argv获取命令行参数
  • 使用open()read()操作文件
  • 使用python re模块匹配行

  • 你可能对Pyp感兴趣。引用我的其他答案:

    "The Pyed Piper", or pyp, is a linux command line text manipulation
    tool similar to awk or sed, but which uses standard python string and
    list methods as well as custom functions evolved to generate fast
    results in an intense production environment.


    真正的问题是变量行总是有一个值。"未找到匹配项"的测试是是否存在匹配项,因此代码"if line==none:"应替换为"else:"