2009-12-17 23 views
45

Tôi cần một cách tìm kiếm tệp bằng grep thông qua cụm từ thông dụng từ dòng lệnh Unix. Ví dụ: khi tôi nhập vào dòng lệnh:Grep và Python

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

Tôi cần biểu thức chính quy 'RE' để tìm kiếm trong tệp và in ra các dòng khớp.

Dưới đây là đoạn code tôi có:

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' 

Nhưng khi tôi nhập một từ mà không phải là hiện tại, no matches found không in

+0

Nếu bạn thực sự muốn biểu thức chính quy kiểu python trong grep, tùy chọn --perl-regex để gre p thực sự gần gũi. Nó cung cấp cho bạn hỗ trợ biểu thức chính quy perl. (Ngoài ra, tùy chọn không thích hợp yêu thích của tôi để grep là --color = always) –

Trả lời

3
  1. sử dụng sys.argv để có được những dòng lệnh thông số
  2. sử dụng open(), read() để thao tác tệp
  3. sử dụng Python re module để chiếu ch dòng
59

Câu hỏi tự nhiên là tại sao không chỉ sử dụng grep ?! Nhưng giả sử bạn không thể ...

import re 
import sys 

file = open(sys.argv[2], "r") 

for line in file: 
    if re.search(sys.argv[1], line): 
     print line, 

Những điều cần lưu ý:

  • search thay vì match để tìm bất cứ nơi nào trong chuỗi
  • dấu phẩy (,) sau khi loại bỏ print vận chuyển trở lại (dòng sẽ có một)
  • argv bao gồm tên tệp python, do đó, các biến cần phải bắt đầu tại 1

Điều này không xử lý nhiều đối số (như grep không) hoặc mở rộng các ký tự đại diện (như vỏ Unix). Nếu bạn muốn chức năng này, bạn có thể sử dụng chức năng này:

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, 
+5

bạn nên biên dịch regex của mình trước khi sử dụng các vòng lặp. – ghostdog74

+3

Điều này có hai phiếu bầu xuống và tôi không biết tại sao. Bất cứ ai downvoted muốn để lại một bình luận? Tôi biết bạn có thể thêm regex biên soạn vv, nhưng tôi nghĩ rằng sẽ làm giảm sự rõ ràng của câu trả lời. Tôi không nghĩ rằng có bất cứ điều gì không chính xác, và tôi đã chạy mã, không giống như một số câu trả lời khác –

+0

Câu trả lời này là hoàn hảo cho tôi cảm ơn. Chỉ cần một câu hỏi nhanh như thế nào tôi sẽ in nếu không có trận đấu đã được tìm thấy? – David

5

Chuyển thể từ một grep in python.

Chấp nhận một danh sách các tên tập tin qua [2:], không có xử lý ngoại lệ:

#!/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:] công trình, nếu bạn chạy nó như một thực thi độc lập, có nghĩa

chmod +x

đầu tiên

+0

sự khác nhau giữa 're.match' và' re.search' là gì? – OscarRyz

+2

@OscarRyz xem [Câu trả lời hàng đầu của Nick Fortescue] (http://stackoverflow.com/a/1921932/327074): "' tìm kiếm' thay vì 'đối sánh' để tìm bất kỳ vị trí nào trong chuỗi" – icc97

2

Bạn có thể quan tâm đến pyp. Trích dẫn của tôi khác answer:

"The Pyed Piper", hoặc pyp, là một Linux dòng lệnh thao tác văn bản công cụ tương tự như awk hoặc sed, nhưng trong đó sử dụng chuỗi python tiêu chuẩn và phương pháp danh sách cũng như các chức năng tùy chỉnh phát triển để tạo ra kết quả nhanh chóng trong một môi trường sản xuất dữ dội.

7

ngắn gọn và bộ nhớ hiệu quả:

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

Nó hoạt động như egrep (không xử lý lỗi quá nhiều), ví dụ:

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

Và đây là một trong những-liner:

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" 
+1

Điều này có thể được làm lại bằng trình tạo và thực tế sẽ không có trí nhớ. – vy32

+0

Cảm ơn bạn đã chỉ ra điều đó. Tôi đã cập nhật câu trả lời chỉ sử dụng trình lặp. –

+0

Tuyệt vời. Hoàn thành rất tốt. – vy32