2009-12-17 10 views
45

Necesito una forma de buscar un archivo usando grep a través de una expresión regular de la línea de comandos de Unix. Por ejemplo cuando escribo en la línea de comandos:Grep y Python

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

necesito la expresión regular 'RE' que se debe buscar en el archivo e imprimir las líneas coincidentes.

Aquí está el código que tengo:

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' 

Pero cuando entro en una palabra que no está presente, no se imprime no matches found

+0

Si realmente desea expresiones regulares de estilo python en grep, la opción --perl-regex para gre p está realmente cerca. Le da soporte de expresiones regulares estilo perl. (Además, mi opción favorita menos utilizada para grep es --color = always) –

Respuesta

3
  1. uso sys.argv para obtener los parámetros de la línea de comandos
  2. use open(), read() para manipular el archivo
  3. utilice Python re module para tapete ch líneas
59

La pregunta natural es ¿por qué no usar grep ?! Pero suponiendo que no se puede ...

import re 
import sys 

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

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

A tener en cuenta:

  • search en lugar de match encontrar en cualquier parte de la cadena
  • coma (,) después print elimina retorno de carro (Line tener uno)
  • argv incluye el nombre del archivo pitón, por lo que las variables tienen que empezar a 1

Esto no maneja múltiples argumentos (como grep does) o expande comodines (como el shell de Unix). Si desea En esta funcionalidad se puede conseguir utilizando el siguiente:

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

debe compilar su expresión regular antes de usar los bucles. – ghostdog74

+3

Esto tiene dos votos abajo y no tengo idea de por qué. ¿Alguien que votó negativamente quiere dejar un comentario? Sé que podrías agregar compilación de expresiones regulares, etc., pero pensé que eso restaría claridad a la respuesta. No creo que haya nada incorrecto, y he ejecutado el código, a diferencia de algunas de las otras respuestas –

+0

Esta respuesta fue perfecta para mí, gracias. Solo otra pregunta rápida ¿cómo imprimiría si no se encontraron coincidencias? – David

5

adaptación de una grep in python.

acepta una lista de nombres de archivos a través de [2:], no hace el manejo de excepciones:

#!/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:] trabajos, si se ejecuta como un ejecutable independiente, lo que significa

chmod +x

primera

+0

¿cuál es la diferencia entre 're.match' y' re.search'? – OscarRyz

+2

@OscarRyz ver [respuesta superior de Nick Fortescue] (http://stackoverflow.com/a/1921932/327074): "' search' en lugar de 'match' para buscar en cualquier lugar de la cadena" – icc97

2

Usted podría estar interesado en pyp. Citando mi otra answer:

"El PYED Piper", o PEP, es una línea de comandos de Linux manipulación de texto herramienta similar a awk o sed, sino que utiliza cadena de Python estándar y métodos de listas, así como las funciones personalizadas evolucionado para generar resultados rápidos en un entorno de producción intenso.

7

concisa y eficiente de la memoria:

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

Funciona como egrep (sin control de errores demasiado), por ejemplo:

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

Y aquí es la de una sola línea:

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

Esto podría rehacerse con un generador y prácticamente no tendría memoria. – vy32

+0

Gracias por señalar eso. Actualicé la respuesta usando solo iteradores. –

+0

Eso es genial. Muy bien hecho. – vy32