在Python中,如何打印不包含特定字符串的行,而不是包含特定字符串的行:

20 投票
4 回答
155206 浏览
提问于 2025-04-18 15:23

我正在尝试压缩一个非常大的日志文件。为此,我需要删除所有包含“StatusRequest”和“StatusResponse”这两个字符串的行,同时打印出其他不包含这些字符串的行。到目前为止,我的代码如下(可以在命令提示符下运行):

   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()

其实你只需要关注脚本的最后部分就可以回答我的问题……不过,我不太明白为什么这段代码不管用……它还是输出了每一行。我已经尝试过调换一下“not”的位置,让它更符合语法,但代码没有任何变化。非常感谢任何帮助 :)

4 个回答

1

这里的 not 可以用来否定括号里面的表达式,就像你最开始写的那样。你只需要修改一下它所否定的内容,也就是检查字符串是否在 line 里面:

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

2

你需要把每个条件单独写出来:

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

把这一行替换成:

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

换成这一行:

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

虽然不是特别优雅,但这样做可以解决问题。我不太确定有没有更快的方法来比较两条字符串。

28

问题不在于你使用了 not,而在于 or 的意思可能和你想的不一样(如果你仔细想想,这个意思是不能成立的):

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

你在问表达式 ("StatusRequest" or "StatusResponse") 是否出现在 line 中。但这个表达式其实和 "StatusRequest" 是一样的。

换句话说,你并不是在说“如果这两个都不在 line 中”。Python 没有 neithernone 这样的函数,但它有一个 any 函数,所以你可以这样做:

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

这虽然没有英语那么简洁;在英语中,你可以直接说“如果 'StatusRequest' 和 'StatusResponse' 这两个值都不在 line 中”,但在 Python 中,你得说“如果即将出现的值中没有 'StatusRequest' 和 'StatusResponse'”。

或者,在这种情况下,也可以更简单地这样写:

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

(另外,注意你可以使用 not in,而不是先用 in 然后再否定整个表达式。)

撰写回答