[python] Chercher une chaine dans un fichier [Fermé]

Signaler
-
 ccadic -
Bonjour.

J'apprends python et j'aimerai faire un petit script qui permet d'ouvrir un fichier et chercher dans celui-ci des chaines de caractères (qui seront des lignes de codes d'un autre langage) et les afficher avec un print par la suite. Comment est ce que je dois m'y prendre ?

Merci d'avance.
A voir également:

19 réponses

Messages postés
32840
Date d'inscription
mercredi 29 août 2001
Statut
Modérateur
Dernière intervention
21 octobre 2019
15 539
Hello !

Voici un exemple simple:
On recherche les lignes contenant "coucou" dans le fichier fichier.txt et on les affiche:

#!/usr/bin/python
# -*- coding: iso-8859-1 -*-

chaine = "coucou" # Texte à rechercher

fichier = open("fichier.txt","r")
for ligne in fichier:
    if chaine in ligne:
        print ligne
fichier.close()

28
Merci

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

CCM 65492 internautes nous ont dit merci ce mois-ci

Wa, interessant. Et si je veux chercher plusieurs chaines et les afficher ligne par ligne. Je dois creer une classe c'est ça ? je ne parviens pas a faire cela. Je peux creer une autre variable avec chaine2 = "truc" et apres mettre un elif print ligne. Mais s'il y a plus de 30 types de chaines a chercher ca risque d'etre long.
As-tu une idée ?

Merci de ton aide.
Messages postés
21331
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
30 octobre 2019
3 544
Salut,

je ne connais pas encore python.
en revanche je pense que je peux te repondre à
chaines est déclaré, mais pour chaine et ligne, cela correspond à quoi.

En fait chaines n'est pas non plus declarée, plutôt initialisée.

les variables ligne, chaine, prendent vie dès leur utilisation, sans avoir besoin d'une déclaration comme on fait en C par exemple.

Sebsauvage utilise ligne et chaine pour avoir une cohérence en ce qu'il a fait, mais tu peux utilser n'importe quoi (garde quand même une cohérence entre ce que tu veux faire et les noms de variables que tu utilises :-))

Exemple :

fichier = open("fichier.txt","r")
for line in fichier:
    for motin chaines:
        if motin line:
            print line
fichier.close()


Messages postés
32840
Date d'inscription
mercredi 29 août 2001
Statut
Modérateur
Dernière intervention
21 octobre 2019
15 539
il n'y a aucun \n dans ton code

Si, là:

o.write('%s\n' % i.replace(entr1,entr2))
Messages postés
32840
Date d'inscription
mercredi 29 août 2001
Statut
Modérateur
Dernière intervention
21 octobre 2019
15 539
Et si je veux chercher plusieurs chaines et les afficher ligne par ligne. Je dois creer une classe c'est ça ?

pas obligatoirement.

C'est à toi de choisir si tu veux programmer sous forme de classes ou non.


Mais s'il y a plus de 30 types de chaines a chercher ca risque d'etre long.

On pourrait faire comme ça:
#!/usr/bin/python
# -*- coding: iso-8859-1 -*-

chaines = ["coucou1",
           "coucou2",
           "coucou3"] # Texte à rechercher

fichier = open("fichier.txt","r")
for ligne in fichier:
    for chaine in chaines:
        if chaine in ligne:
            print ligne
fichier.close()
Messages postés
43
Date d'inscription
jeudi 27 janvier 2005
Statut
Membre
Dernière intervention
28 août 2007

Bonjour

Je viens de lire ton code et deux questions me viennent.

#!/usr/bin/python
# -*- coding: iso-8859-1 -*-

chaines = ["coucou1",
"coucou2",
"coucou3"] # Texte à rechercher

fichier = open("fichier.txt","r")
for ligne in fichier:
for chaine in chaines:
if chaine in ligne:
print ligne
fichier.close()

chaines est déclaré, mais pour chaine et ligne, cela correspond à quoi.

Et ci après rechercher coucou tu veux le remplacer par au revoir dans ton fichier texte, tu fais comment.


Je te pose ces deux questions car j'ai le problème en ce moment.

Je te balance mon code.

print "début" # début procédure

from os import chdir
chdir("/Volumes/GERTEX/_test/")

import shutil, string, re

obfic = open("taglist.xml","r") # Lecture ds le fichier taglist des 60 dernières lignes
lignes = obfic.readlines()[-59:]
obfic.close()

obfic = open("tampon_taglist.xml","w") # Copie ds le fichier tampon_taglist des 60 dernières lignes
obfic.write("".join(lignes))
s = '>442<'
re.sub(r'\s','>444<',s)
obfic.close()

shutil.copyfile('tampon_taglist.xml','nouveau_taglist.xml') # Copie de taglist.xml dans nouveau_taglist.xml

print "fin" # fin procédure

Le principe est le suivant, je copis les 60 dernières lignes d'un fichier que je recopis ds un fichier tampon. Dans celui-ci je remplace ma chaine de caractère 442, par 444. Une fois mit en forme je souhaite recopier la globaliter de ce fichier dans mon fichier d'origine en avant dernière ligne.

Si tu peux m'aider ... merci d'avance.
Messages postés
21331
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
30 octobre 2019
3 544
Re,

j'ai oublié les espaces. je n'arrive pas à editer mon message
fichier = open("fichier.txt","r")
for line in fichier:
    for mot in chaines:
        if mot in line:
            print line
fichier.close()
Messages postés
32840
Date d'inscription
mercredi 29 août 2001
Statut
Modérateur
Dernière intervention
21 octobre 2019
15 539
Voilà, exactement.

C'est le for qui va créer la variable chaine et ligne et lui donner succesivement chacune des valeurs de fichier et chaines (respectivement).
Messages postés
43
Date d'inscription
jeudi 27 janvier 2005
Statut
Membre
Dernière intervention
28 août 2007

Bonjour

J'ai un petit problème, de recherche de chaine de caractères.

J'ai bien fait comme toi la boucle, mais maintenant j'aimerai l'instaurer ds une

(entr1, entr2) = (StringVar(),StringVar())

def toto():

s = open('/Volumes/GERTEX/_test/tampon_taglist.txt','r')
o = open('/Volumes/GERTEX/_test/tampon1_taglist.txt','w')

for i in s.readlines():
o.write('%s\n' % i.replace(entr1,entr2))

s.close()
o.close()

bou1 = Button(fen1, text='Valider', command = toto)

Et là qund je compile il s'arrête sur la ligne:
o.write('%s\n' % i.replace(entr1,entr2))

Je pense que cela provient de la déclaration des variables mais je ne comprends pas le pb.


Voici le script au complet:

from Tkinter import *
from os import chdir
chdir("/Volumes/GERTEX/_test/")
#chdir("/_test/")
import shutil, string, re

obfic = open("taglist.txt","r")# Lecture ds le fichier taglist des 60 dernières lignes
lignes = obfic.readlines()[-59:]
obfic.close()

obfic = open("tampon_taglist.txt","w") # Copie ds le fichier tampon_taglist des 60 dernières lignes
obfic.write("".join(lignes))
obfic.close()

#Programme princioal

fen1 = Tk()
fen1.title("Calcul des valeurs du fichiers TAG")
fen1.geometry('500x300')

#(franc1,franc2,franc3,franc4,franc5,franc6,euro) = (StringVar(),StringVar(),StringVar(),StringVar(),StringVar(),StringVar(),StringVar())
(entr1, entr2) = (StringVar(),StringVar())

def seteuro():

s = open('/Volumes/GERTEX/_test/tampon_taglist.txt','r')
o = open('/Volumes/GERTEX/_test/tampon1_taglist.txt','w')

for i in s.readlines():
# o.write('%s\n' % i.replace(franc1,franc2)),('%s\n' % i.replace(franc3,franc4)),('%s\n' % i.replace(franc5,franc6))
o.write('%s\n' % i.replace(entr1,entr2))

s.close()
o.close()

#Listing des objets

txt1 = Label(fen1, text = 'Ancien ID1:')
txt2 = Label(fen1, text = 'Nouveau ID1:')
txt3 = Label(fen1, text = 'Ancien ID2:')
txt4 = Label(fen1, text = 'Nouveau ID2:')
txt5 = Label(fen1, text = 'Ancien mnemonic:')
txt6 = Label(fen1, text = 'Nouveau mnemonic:')
#txt7 = Label(fen1, text = '')

bou1 = Button(fen1, text='Valider', command = seteuro)
bou2 = Button(fen1, text='Quitter', command = fen1.destroy)

entr1 = Entry(fen1)
entr2 = Entry(fen1)
entr3 = Entry(fen1)
entr4 = Entry(fen1)
entr5 = Entry(fen1)
entr6 = Entry(fen1)
#entr7 = Entry(fen1)


#Mise en place

txt1.grid(row =0)
txt2.grid(row =1)
txt3.grid(row =2)
txt4.grid(row =3)
txt5.grid(row =4)
txt6.grid(row =5)
#txt7.grid(row =5)

bou1.grid(row =10 ,column =1)
bou2.grid(row =10 ,column =2)

entr1.grid(row =0,column =1)
entr2.grid(row =1,column =1)
entr3.grid(row =2,column =1)
entr4.grid(row =3,column =1)
entr5.grid(row =4,column =1)
entr6.grid(row =5,column =1)
#entr7.grid(row =6,column =1)

#Démarrage
fen1.mainloop()
Messages postés
32840
Date d'inscription
mercredi 29 août 2001
Statut
Modérateur
Dernière intervention
21 octobre 2019
15 539
Je pense que cela provient de la déclaration des variables mais je ne comprends pas le pb.

.replace() n'est pas capable de travailler avec les variables tkinter.
.replace() attend des chaînes de caractères standard Python, pas des variable tkinter (StringVar() est une variable tkinter).


Donc il faudrait écrire:
def toto(entr1,entr2):
    s = open('/Volumes/GERTEX/_test/tampon_taglist.txt','r')
    o = open('/Volumes/GERTEX/_test/tampon1_taglist.txt','w')

    for i in s.readlines():
        o.write('%s\n' % i.replace(entr1,entr2))

    s.close()
    o.close() 


en mettant par exemple:
entr1='coucou'
entr2='kiki'
toto(entr1,entr2)




StringVar() n'est utile que pour lire ou écrire une valeur dans une interface graphique tkinter.
Il est inutile pour les programme Python eux-mêmes.


PS: Utilise le bouton "code" pour mettre ton code source dedans.
Messages postés
43
Date d'inscription
jeudi 27 janvier 2005
Statut
Membre
Dernière intervention
28 août 2007

Bonjour

En fait je veux au travers d'une fenetre saisir mes chaines de caractère que je cherche et celle que je remplace.

Et en appuyant sur mon bouton les changer ds mes fichiers txt.

Je vais tester la modif que tu m'as donné.

@+ je pense.
Messages postés
43
Date d'inscription
jeudi 27 janvier 2005
Statut
Membre
Dernière intervention
28 août 2007

Le prob c'est que je ne peux pas mettre entr1='titi' et entr2='tot' dans mon prog en dur.

Tu vois ce que je veux dire. Je veux que la saisie des champs soient égales a mes deux variables.

ou alors je n'ai pas compris
Messages postés
43
Date d'inscription
jeudi 27 janvier 2005
Statut
Membre
Dernière intervention
28 août 2007

Sle seb

Merci pour toute tes infos, car cel fonctionne du tonnerre de dieu.

Mais j'ai deux problèmes, qui me reste à identifier.

Le premier c'est que dans mon fichier txt, que j'exploite, j'ai des espaces entre chaque ligne mais je ne vois pas de quel paramètre cela provient.

Le deuxième c'est qu'après avoir créer mon executable avec py2exe j'ai une fenetre commande dos qui s'ouvre à chaque fois et j'aimerai la faire disparaitre.

Et soyons vous je cherche à integrer une sorte d'explorateur pour aller chercher mes fichiers qui vont bien peux tu me tuyauter?

Merci encore.
Messages postés
32840
Date d'inscription
mercredi 29 août 2001
Statut
Modérateur
Dernière intervention
21 octobre 2019
15 539
Il faut que tu lises ça:
https://sebsauvage.net/python/gui/index_fr.html

ça t'expliquera comment lire une valeur d'un champ tkinter et récupérer la chaîne de caractères.
Messages postés
43
Date d'inscription
jeudi 27 janvier 2005
Statut
Membre
Dernière intervention
28 août 2007

Ok merci pour les infos et à partir de cela je devrai résoudre mon problème je pense.

Sinon tu as compri le principe de mon application.
Tien, j'ai essayé ton petit exemple sebsauvage, et j'ai une question, comment est ce que ca se fait qu'il y ait un saut de ligne automatique a chaque chaine trouvée ?

coucou

coucou2

coucou3

Tout se joue dans 'ligne' je suppose. Désolé pour cette question ininteressante :p
Messages postés
32840
Date d'inscription
mercredi 29 août 2001
Statut
Modérateur
Dernière intervention
21 octobre 2019
15 539
ah oui c'est normal:

On récupère la ligne (contenant le caractère de retour à la ligne), et quand j'écris les lignes, j'ajoute \n.
ça fait donc deux retours à la ligne.

C'est une erreur.
Je ne comprends pas, il n'y a aucun \n dans ton code, et dans le fichier fichier.txt il y a juste:

coucou1
coucou2
coucou3

Je ne vois donc pas ou tu rajoute le \n. C'est un mystère pour moi :p
merci
Ah d'accord, je parlais en fait de celui-ci:

#!/usr/bin/python
# -*- coding: iso-8859-1 -*-

chaines = ["coucou1",
           "coucou2",
           "coucou3"] # Texte à rechercher

fichier = open("fichier.txt","r")
for ligne in fichier:
    for chaine in chaines:
        if chaine in ligne:
            print ligne
fichier.close()


ce qui donne:

ruga@ubuntu:~/Desktop/docs/python$ cat fichier.txt
coucou1
coucou2
coucou3
ruga@ubuntu:~/Desktop/docs/python$ python test.py
coucou1

coucou2

coucou3

ruga@ubuntu:~/Desktop/docs/python$

Ce n'est pas un saut de ligne automatique ?
Messages postés
32840
Date d'inscription
mercredi 29 août 2001
Statut
Modérateur
Dernière intervention
21 octobre 2019
15 539
L'instruction print ajoute un saut de ligne après avoir affiché sa chaîne.
Messages postés
43
Date d'inscription
jeudi 27 janvier 2005
Statut
Membre
Dernière intervention
28 août 2007

Bonjour

J'ai encore un dernier petit problème.

Comment je peux ecrire à la suite de mon fichier sans pour autant ecraser ce qui existe deja.


Merci d'avance.
Messages postés
32840
Date d'inscription
mercredi 29 août 2001
Statut
Modérateur
Dernière intervention
21 octobre 2019
15 539
Comment je peux ecrire à la suite de mon fichier sans pour autant ecraser ce qui existe deja.

f = open('monfichier.txt','a')


'a' pour append (ajouter).
Messages postés
43
Date d'inscription
jeudi 27 janvier 2005
Statut
Membre
Dernière intervention
28 août 2007

Merci impec cela fonctionne.

Il me reste un petit soucis.
Cette syntaxe fonctionne, mais je voudrai rajourter d'autres variables, mais le remplacement se fait que sur le premier couple.

As tu une idée?


o.write('%s\n' % i.replace(entr1.get(),entr2.get()))

o.write('%s\n' % i.replace(entr1.get(),entr2.get()),
'%s\n' % i.replace(entr3.get(),entr4.get()))

Merci d'avance
Messages postés
32840
Date d'inscription
mercredi 29 août 2001
Statut
Modérateur
Dernière intervention
21 octobre 2019
15 539
Tu peux chaîner les remplacements. Exemple:

>>> a='coucou'
>>> print a.replace('o','*').replace('c','C')
C*uC*u
>>>
Bonjour à tous !

J'ai une question. Est t-il est possible de chercher plusieurs chaines particulières dans un fichier sachant que cette chaine n'est pas une chaine "en dur". Le mieux serait un exemple:

LaChaine = "bonne journée|soirée"

Lorsque le script cherche LaChaine dans le fichier, est ce qu'il est possible de faire en sorte qu'il return bien un des 2 (soit "bonne journée", soit "bonne soirée", tout depend de celui qui est dans le fichier).
Mais bien sur le signe '|' ne fonctionne pas ici. Donc en fait, je cherche une sorte d'opérateur qui est utilisé pour faire un OU (j'ai cru comprendre que le or avait tout autre utilité).



Autre chose, lorsqu'il s'agit d'un emplacement vide, par exemple accepter toutes les chaines de type:

LaChaine = "Il faut * sinon ca ne marchera pas" (désolé exemple bidon)

le '*' est l'emplacement qui peut etre n'importe quoi. Exemple: 'Faire ceci' ou encore 'Manger cela'
C'est à dire que je cherche a trouver toutes les chaines qui commencent par "Il faut" [avec ici, peu importe les mots] et qui terminent par "sinon ca ne marchera pas". Le but étant de chercher toutes les chaines comme :
"Il faut beaucoup manger sinon ca ne marchera pas", "Il faut faire son lit tous les matins sinon ca ne marchera pas", "il faut boire du café le matin sinon ca ne marchera pas". Bref vous avez compris :]

En esperant que mes questions sont compréhensibles ...
Merci d'avance ! :]
Messages postés
32840
Date d'inscription
mercredi 29 août 2001
Statut
Modérateur
Dernière intervention
21 octobre 2019
15 539
Je vois ce que tu veux faire.
Tu peux utiliser les expressions régulières (module re)

Pour le premier:
'bonne "journée"|"soirée"'
(syntaxe à vérifier, je n'ai pas testé)


Pour le second:
"Il faut (.+?) sinon ca ne marchera pas" 


Messages postés
32840
Date d'inscription
mercredi 29 août 2001
Statut
Modérateur
Dernière intervention
21 octobre 2019
15 539
Le premier c'est que dans mon fichier txt, que j'exploite, j'ai des espaces entre chaque ligne mais je ne vois pas de quel paramètre cela provient.

Est-ce que tu travaille sous Unix/Linux ?

En fait, il peut y avoir 3 types de retour à la ligne différents pour un fichier texte: le mode MS-Dos, le mode Unix et le mode Macintosh.
Le mode MS-Dos utilise 2 caractères (\r\n) ce qui peut dans certains cas provoquer deux retours à la ligne.

Difficile à dire: je n'ai ni le programme ni le fichier à traiter.



Le deuxième c'est qu'après avoir créer mon executable avec py2exe j'ai une fenetre commande dos qui s'ouvre à chaque fois et j'aimerai la faire disparaitre.

Dans ton script py2exe, au lieu de faire: console=["monprogramme.py"]
fais: windows=["monprogramme.py"]


Et soyons vous je cherche à integrer une sorte d'explorateur pour aller chercher mes fichiers qui vont bien peux tu me tuyauter?

Si tu utilises tkinter pour l'interface graphique, il y a des boites de dialogue toutes prêtes pour la sélection de fichiers ou de répertoires.
Exemples: https://www.sebsauvage.net/python/snyppets/#tkinter_dialogs

Messages postés
43
Date d'inscription
jeudi 27 janvier 2005
Statut
Membre
Dernière intervention
28 août 2007

Ok je te remercis pour les infos.

Je vais me pencher pour essayer de selectionner des programmes via un explorateur.

Je te recontacterai surement pour des infos.


Merci encore.
Bonjour,

J'aurais voulu savoir s'il est possible d'effectuer la même chose mais sur l'ensemble du texte, non sur chaque ligne du texte. C'est-à-dire une recherche globale du mot dans l'ensemble du texte, sans utiliser une boucle qui cherche ligne par ligne.

Merci !
Bonjour à tous,

J'ai une demande un peu différente.

J'aimerai chercher, dans un répertoire donné, le nom de tous les fichier de ce répertoire contenant un certain mot dans le fichier.

Comment dois-je procéder ??

Merci d'avance !!