Grep 和 Python

问题描述 投票:0回答:8

我需要一种在 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
不会打印

python regex grep
8个回答
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, end='\n')

注意事项:

  • search
    而不是
    match
    来查找字符串中的任意位置
  • ,
    后的
    逗号 (
    print
    ) 删除回车符(行将有一个)
  • argv
    包含python文件名,因此变量需要从1开始

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

#!/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='')

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 已成为惰性函数。


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]
resp
sys.argv[2:]
可以工作,如果您将其作为独立的可执行文件运行,这意味着

chmod +x

首先


5
投票
  1. 使用
    sys.argv
    获取命令行参数
  2. 使用
    open()
    ,
    read()
    操作文件
  3. 使用 Python re 模块来匹配行

4
投票

您可能对 pyp 感兴趣。引用我的另一个答案

“The Pyed Piper”,即 pyp,是一个 Linux 命令行文本操作工具 类似于 awk 或 sed 的工具,但它使用标准 python 字符串和 列表方法以及自定义函数不断发展以快速生成 导致生产环境紧张。


3
投票

您可以使用 python-textops3 :

from textops import *

print('\n'.join(cat(f) | grep(search_term)))

使用 python-textops3,您可以通过管道使用类似 UNIX 的命令


2
投票

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


1
投票

不确定你的问题对我来说是否清楚,但要修复你的代码,只需更改你的 if 表达式,如下所示:

import re
import sys

search_term = sys.argv[1]
f = sys.argv[2]
r = None
n = 0
with open(f, 'r') as file:
    for line in file:
        n=n+1
        r = re.search(search_term, line)
        if r:
            print(f"{line} found at line {n}")
if not r:
    print('no matches found')

PS:我在Python 3.8.10上测试过

如果你想使用 grep 你可以

grep -E '(.*)word(.*)' file.txt || echo "pattern not found"
© www.soinside.com 2019 - 2024. All rights reserved.