簡體   English   中英

grep 和 Python

[英]Grep and 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不會打印

自然的問題是為什么不直接使用 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,

簡潔和高效的內存:

#!/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 已成為惰性函數。

改編自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

第一的

  1. 使用sys.argv獲取命令行參數
  2. 使用open()read()來操作文件
  3. 使用Python re 模塊匹配行

您可能對pyp感興趣。 引用我的另一個答案

“The Pyed Piper”,或 pyp,是一個類似於 awk 或 sed 的 linux 命令行文本操作工具,但它使用標准的 python 字符串和列表方法以及演變為在密集的生產環境中生成快速結果的自定義函數。

真正的問題是變量 line 總是有一個值。 “未找到匹配項”的測試是是否存在匹配項,因此代碼“if line == None:”應替換為“else:”

您可以使用 python-textops3 :

from textops import *

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

使用 python-textops3,您可以使用帶有管道的類 unix 命令

你有沒有簽署過 None 的線路? (即“行=無”)

不確定您的問題對我來說是否清楚,但要修復您的代碼,只需更改您的 if 表達式,如下所示:

import re
import sys

search_term = sys.argv[1]
f = sys.argv[2]
r = None
n = 0
for line in open(f, 'r'):
    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"

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM