Устранить повторяющиеся строки и записать в файл - PullRequest
0 голосов
/ 03 апреля 2020

file1.txt имеет следующие строки:

[SUM]   0.00-34.53  sec  2.11 GBytes   524 Mbits/sec                  sender    
[SUM]   0.00-34.53  sec  2.11 GBytes   524 Mbits/sec                  sender    
[SUM]   0.00-34.62  sec  2.36 GBytes   586 Mbits/sec                  sender    
[SUM]   0.00-34.62  sec  2.36 GBytes   586 Mbits/sec                  sender 
[SUM]   0.00-34.75  sec  2.39 GBytes   591 Mbits/sec                  receiver  
[SUM]   0.00-34.75  sec  2.39 GBytes   591 Mbits/sec                  receiver  
[0]   0.00-34.53  sec  0.00 Bytes  0.00 bits/sec                  receiver 
[0]   0.00-34.75  sec  0.00 Bytes  0.00 bits/sec                  sender 

печать строк, начинающихся с [SUM] и заканчивающихся отправителем и получателем, в другой текстовый файл-file2.txt.

ниже это код:

with open(r"C:\Users\file1.txt", 'r') as f:

 contents = f.read()
 s=contents

def my_function1():

 regex = "^\s*\[SUM\]\s*[0-9\-\.]+\s+sec(?!\s+0\.00 Bytes).*sender.*"   
 items=re.findall(regex,s,re.MULTILINE)
 for y in items:
   file=open('file2.txt', "a")
   file.write(str(y))
   file.write("\n")
   file.close()


def my_function2():

 regex = "^\s*\[SUM\]\s*[0-9\-\.]+\s+sec(?!\s+0\.00 Bytes).*receiver.*"   
 items=re.findall(regex,s,re.MULTILINE)
 for y in items:
   file=open('file2.txt', "a")
   file.write(str(y))
   file.write("\n")
   file.close()
   #print(y)

my_function1()

my_function2()

, который записывает вывод в file2.txt как:

[SUM]   0.00-34.53  sec  2.11 GBytes   524 Mbits/sec                  sender    
[SUM]   0.00-34.53  sec  2.11 GBytes   524 Mbits/sec                  sender    
[SUM]   0.00-34.62  sec  2.36 GBytes   586 Mbits/sec                  sender    
[SUM]   0.00-34.62  sec  2.36 GBytes   586 Mbits/sec                  sender
[SUM]   0.00-34.62  sec  2.36 GBytes   586 Mbits/sec                  sender 
[SUM]   0.00-34.75  sec  2.39 GBytes   591 Mbits/sec                  receiver  
[SUM]   0.00-34.75  sec  2.39 GBytes   591 Mbits/sec                  receiver

Ожидается: печать только один раз

[SUM]   0.00-34.53  sec  2.11 GBytes   524 Mbits/sec                  sender
[SUM]   0.00-34.62  sec  2.36 GBytes   586 Mbits/sec                  sender
[SUM]   0.00-34.75  sec  2.39 GBytes   591 Mbits/sec                  receiver 

Ответы [ 3 ]

1 голос
/ 03 апреля 2020

Вам не нужен модуль re здесь, и вам не нужно загружать все в память:

with open(r"C:\Users\file1.txt", 'r') as f, open('file2.txt', "w") as file:
    seen = set()     # use a set to only keep distinct lines
    for line in f:   # iterate the input file
        lr = line.rstrip()
        if line.startswith('one') and lr.endswith('apple'):
            if lr not in seen:
                seen.add(lr)
                _ = file.write(line)

Если поиск действительно более сложный и требует модуля re, я бы все равно придерживайтесь обработки по одной строке за раз и скомпилируйте регулярное выражение за пределами l oop:

with open(r"C:\Users\file1.txt", 'r') as f, open('file2.txt', "w") as file:
    seen = set()     # use a set to only keep distinct lines
    rx = re.compile(pattern)
    for line in f:   # iterate the input file
        lr = line.rstrip()
        if rx.match(lr):
            if lr not in seen:
                seen.add(lr)
                _ = file.write(line)

Если вам нужно выполнить поиск по 2 шаблонам и убедиться, что записаны совпадения для первого перед совпадениями для вторых вы можете использовать:

patterns = ["^\s*\[SUM\]\s*[0-9\-\.]+\s+sec(?!\s+0\.00 Bytes).*sender.*",
            "^\s*\[SUM\]\s*[0-9\-\.]+\s+sec(?!\s+0\.00 Bytes).*receiver.*"]
rxs = [re.compile(pattern) for pattern in patterns]

with open(r"C:\Users\file1.txt", 'r') as f:
    data = [[], []]
    seen = set()     # use a set to only keep distinct lines
    for line in f:   # iterate the input file
        lr = line.rstrip()
        for i, rx in enumerate(rxs):
            if rx.match(lr):
                if lr not in seen:
                    seen.add(lr)
                    data[i].append(line)
with open('file2.txt', "w") as file:
    for lst in data:
        for line in lst:
            _ = file.write(line)
    print(file.getvalue())

Это дает ожидаемое:

[SUM]   0.00-34.53  sec  2.11 GBytes   524 Mbits/sec                  sender    
[SUM]   0.00-34.62  sec  2.36 GBytes   586 Mbits/sec                  sender    
[SUM]   0.00-34.75  sec  2.39 GBytes   591 Mbits/sec                  receiver  
1 голос
/ 03 апреля 2020

Просто используйте awk:

$ awk '/^\[SUM]/ && !seen[$0]++' file
[SUM]   0.00-34.53  sec  2.11 GBytes   524 Mbits/sec                  sender
[SUM]   0.00-34.62  sec  2.36 GBytes   586 Mbits/sec                  sender
[SUM]   0.00-34.62  sec  2.36 GBytes   586 Mbits/sec                  sender
[SUM]   0.00-34.75  sec  2.39 GBytes   591 Mbits/sec                  receiver

Как вы видите, вам не нужно такое сложное регулярное выражение, как вы думали, учитывая ваш опубликованный пример ввода, но если вы это сделали, возможно, что-то вроде этого вам ищите (использует GNU awk для \s, с другими awk используйте [[:space:]]):

$ awk '/^\s*\[SUM]\s*[0-9.-]+\s+sec\s.*(sender|receiver)/ && !seen[$0]++' file
[SUM]   0.00-34.53  sec  2.11 GBytes   524 Mbits/sec                  sender
[SUM]   0.00-34.62  sec  2.36 GBytes   586 Mbits/sec                  sender
[SUM]   0.00-34.62  sec  2.36 GBytes   586 Mbits/sec                  sender
[SUM]   0.00-34.75  sec  2.39 GBytes   591 Mbits/sec                  receiver
0 голосов
/ 03 апреля 2020

Если вы хотите получить уникальный список, просто добавьте: list(set(items)) перед записью в файл

...