web-dev-qa-db-fra.com

Grep et Python

J'ai besoin d'un moyen de rechercher un fichier en utilisant grep via une expression régulière à partir de la ligne de commande Unix. Par exemple, lorsque je tape en ligne de commande:

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

J'ai besoin de rechercher l'expression régulière 'RE' dans le fichier et d'imprimer les lignes correspondantes.

Voici le code que j'ai:

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'

Mais quand j'entre un mot qui n'est pas présent, no matches found n'imprime pas

56
David

La question naturelle est pourquoi ne pas simplement utiliser grep?! Mais en supposant que vous ne pouvez pas ...

import re
import sys

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

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

Choses à noter:

  • search au lieu de match pour trouver n'importe où dans la chaîne
  • virgule (,) après que print supprime le retour chariot (la ligne en aura un)
  • argv inclut le nom de fichier python, donc les variables doivent commencer à 1

Cela ne gère pas plusieurs arguments (comme le fait grep) ni les caractères génériques (comme le ferait le shell Unix). Si vous souhaitez cette fonctionnalité, vous pouvez l’obtenir de la manière suivante:

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,
69
Nick Fortescue

Concis et efficace en mémoire:

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

Cela fonctionne comme egrep (sans trop de traitement d'erreur), par exemple:

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

Et voici le one-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"
10

Adapté d'un grep en python .

Accepte une liste de noms de fichiers via [2:], ne gère pas les exceptions:

#!/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:] fonctionne si vous l'exécutez en tant qu'exécutable autonome, ce qui signifie 

chmod +x 

premier

5
miku
  1. utilisez sys.argv pour obtenir les paramètres de ligne de commande
  2. utiliser open(), read() pour manipuler le fichier
  3. utilisez le module Python re module pour faire correspondre les lignes
4
jldupont

Vous pourriez être intéressé par pyp . Citer mon autre répondre

"The Pyed Piper", ou pyp, est une manipulation de texte en ligne de commande sous Linux outil similaire à awk ou sed, mais utilisant une chaîne python standard et Les méthodes de liste ainsi que les fonctions personnalisées ont évolué pour générer rapidement résulte dans un environnement de production intense.

2
Piotr Dobrogost

Le vrai problème est que la ligne de variable a toujours une valeur. Le test "Aucune correspondance trouvée" permet de déterminer s'il existe une correspondance. Le code "if line == None:" doit être remplacé par "else:" 

0
richard