web-dev-qa-db-fra.com

En python, comment puis-je imprimer des lignes qui ne contiennent PAS une certaine chaîne, plutôt que d'imprimer des lignes qui contiennent une certaine chaîne:

J'essaie de condenser un très gros fichier journal, et pour ce faire, je dois éliminer chaque ligne qui contient la chaîne "StatusRequest" et "StatusResponse", tout en imprimant les autres lignes sans cette chaîne. Le code que j'ai jusqu'à présent est le suivant (à exécuter à partir de l'invite de commande):

   if (sys.argv[1])=="--help":
       print ("\n")
       print ("Argument 1: Enter name of '.py' file")
       print ("-i or --input: name of Catalina log")
       print ("-o or --output: file to output to")
       print ("\n")
   if (sys.argv[1])=="-h":
       print ("\n")
       print ("Argument 1: Enter name of '.py' file")
       print ("-i or --input: name of Catalina log")
       print ("-o or --output: file to output to")
       print ("\n")

   else:
       print 'Number of arguments:', len(sys.argv), 'arguments.'
       print 'Argument List:', str(sys.argv)

       Numarg = (len(sys.argv))
       i=1
       while i<=(Numarg-4):
           search1="StatusRequest"
           search2="StatusResponse"
           if (sys.argv[Numarg-2])=="-o":
               outputfile=sys.argv[Numarg-1]

           if (sys.argv[Numarg-2])=="--output":
               outputfile=sys.argv[Numarg-1]

           if (sys.argv[i])=="-i":
               filename=(sys.argv[i+1])

               log=(filename)
               print ("You entered the log: " + log)

               f=open(log, 'r')
               read_data = f.read()
               f.close

               f=open(log, 'r')
               readlines_data=f.readlines()
               f.close()
               i=i+1
           if (sys.argv[i])=="--input":
               filename=(sys.argv[i+1])
               log=(filename)
               print ("You entered the log: " + log)

               f=open(log, 'r')
               read_data = f.read()
               f.close

               f=open(log, 'r')
               readlines_data=f.readlines()
               f.close()
               i=i+1
           for line in readlines_data:
               if not ("StatusRequest" or "StatusResponse") in line:
                   result=line
                   print (line)
       f=open(outputfile, 'a')
       f.write(result + "\n")
       f.close()

Vous pouvez simplement vous concentrer sur la fin du script pour répondre à ma question, vraiment ... Quoi qu'il en soit, je ne sais pas pourquoi cela ne fonctionne pas ... Il émet toujours chaque ligne. Et j'ai déjà essayé de changer la place du pas pour que cela ait plus de sens idiomatiquement, mais cela n'a rien changé avec le code. Toute aide est très appréciée :)

9
user3877194

Le problème n'est pas votre utilisation de not, c'est que or ne signifie pas ce que vous pensez qu'il fait (et si vous y réfléchissez, il ne pouvait pas =):

if not ("StatusRequest" or "StatusResponse") in line:

Vous demandez si l'expression ("StatusRequest" or "StatusResponse") apparaît dans line. Mais cette expression est exactement la même chose que "StatusRequest".

Mettez-le en anglais: vous n'essayez pas de dire "si aucun d'eux n'est en ligne". Python n'a pas de fonction neither/none, mais il a une fonction any, vous pouvez donc le faire:

if not any(value in line for value in ("StatusRequest", "StatusResponse")):

Ce n'est pas aussi agréable que l'anglais; en anglais, vous pouvez simplement dire "si aucune des valeurs" StatusRequest "et" StatusResponse "n'est en ligne", mais en Python, vous devez dire "si aucune des valeurs à venir n'est en ligne, pour les valeurs" StatusRequest " et 'StatusResponse' ".

Ou, peut-être plus simplement dans ce cas:

if "StatusRequest" not in line and "StatusResponse" not in line:

(Notez également que vous pouvez utiliser not in, au lieu d'utiliser in, puis de tout annuler.)

16
abarnert

Remplacez cette ligne:

if not ("StatusRequest" or "StatusResponse") in line:

Avec celui-ci:

if "StatusRequest" not in line and "StatusResponse" not in line:

Pas super élégant, mais ça fera l'affaire. Je ne sais pas s'il existe un moyen plus rapide de comparer deux chaînes par rapport à la même ligne.

3
TheSoundDefense

not peut être utilisé pour annuler l'expression à l'intérieur des parenthèses comme vous l'avez eue pour la première fois. Vous avez juste besoin de modifier ce qu'il annule, c'est-à-dire que la chaîne se trouve dans line:

if not ("StatusRequest" in line or "StatusResponse" in line):

1
stever

Vous devez mettre chaque condition séparément:

for line in readlines_data:
    if ("StatusRequest" not in line) and "(StatusResponse" not in line):
        result = line
        print(line)
1
Christian