Я пытаюсь создать скрипт, который может искать все файлы в определенной папке и извлекать любые строки текста, содержащие ключевое слово или фразу.
Очень новичок в python и не очень понимаю, как собрать воедино несколько предложений от других, которые я видел.
import re
from glob import glob
search = []
linenum = 0
pattern = re.compile("Dawg", re.IGNORECASE) # Compile a case-insensitive regex
path = 'C:\\Users\\Username\\Downloads\Testdataextraction\\Throw it in\\Audit_2022.log'
filenames = glob('*.log')
print(f"\n{filenames}")
with open (path, 'rt') as myfile:
for line in myfile:
linenum += 1
if pattern.search(line) != None: # If a match is found
search.append((linenum, line.rstrip('\n')))
for x in search: # Iterate over the list of tuples
print("\nLine " + str(x[0]) + ": " + x[1])
Это делает все именно так, как я хочу, за исключением того, что я могу видеть только один файл за раз. Моя проблема возникает, когда я пытаюсь удалить «Audit_2022.log» с конца пути = строки.
Python говорит "PermissionError: [Errno 13] Отказано в доступе: "C:\Users\Username\Downloads\Testdataextraction\Throw it in"". Я предполагаю, что это связано с тем, что он просматривает каталог, а не файл, но как я могу заставить его читать несколько файлов?
Спасибо заранее!
Я бы тоже, только не знаю как!
Причина, по которой вы получаете это исключение, заключается в том, что open
нужно имя файла, и если вы дадите ему только путь, он действительно не знает, что делать. Минимальный пример может быть:
path = 'C:\\Users\\Username\\Downloads\Testdataextraction\\Throw it in\\Audit_2022.log'
with open (path, 'rt') as f:
pass
Если файл существует, это должно работать нормально, но если вы измените его на:
path = 'C:\\Users\\Username\\Downloads\Testdataextraction\\Throw it in'
with open (path, 'rt') as f:
pass
Тогда это вызовет исключение.
Я подозреваю, что вы пытаетесь просмотреть все файлы журналов в path
и попробовать каждый из них, например:
import os
path = 'C:\\Users\\Username\\Downloads\Testdataextraction\\Throw it in'
filenames = glob(os.path.join(path, '*.log'))
print(f"\n{filenames}")
for filename in filenames:
with open (filename, 'rt') as myfile:
...
Я только что попробовал это, и вывод дает мне эту ошибку: имена файлов = glob('*.log', root_dir=path) TypeError: glob() получил неожиданный аргумент ключевого слова 'root_dir'
Извините, root_dir не был добавлен до Python 3.10.
Вы можете использовать os.listdir()
, чтобы получить все файлы в каталоге, а затем вложить цикл открытия для каждого file
в каталог:
import os
folder = 'C:\\Users\\Username\\Downloads\Testdataextraction\\Throw it in'
for file in glob(os.path.join(folder, '*.log')):
with open(file, 'rt') as myfile:
for line in myfile:
linenum += 1
if pattern.match(line): # If a match is found
search.append((linenum, line.rstrip('\n')))
Спасибо за ответ Фредди. Я попробовал вышеизложенное и получил это: for file in glob('*.log', os.listdir(folder)): TypeError: glob() takes 1 positional argument but 2 were given
@GitGoodSnek, у меня были неправильные аргументы, попробуйте новый пример, пожалуйста
Дал еще одну трещину for file in glob(os.listdir(folder), '*.log'): TypeError: glob() takes 1 positional argument but 2 were given
@GitGoodSnek, снова отредактировано - работает ли это с новым примером?
Иногда бывает. Это платно вытащить половину строк с ключевым словом в нем. Но не вторая половина почему-то.
@GitGoodSnek, вы ищете подпапки? Что выдает print(glob(os.path.join(folder, '*.log')))
? Убедитесь, что он нашел все файлы
@GitGoodSnek, я немного изменил регулярное выражение, посмотрите, поможет ли это
Он находит все 3 тестовых файла. Но это захватывает только 1 строку из каждого файла. Вместо 2 я ожидаю, что он схватит
Он не нашел строк в файлах с новым регулярным выражением
@GitGoodSnek Не могли бы вы добавить строки, которые вы пытаетесь сопоставить (с объяснением), к своему вопросу, пожалуйста?
Предполагая, что вам также нужно показать имена файлов, вы можете сделать это:
import re
from glob import glob
import os
p = re.compile('Dawg', re.IGNORECASE)
path = r'C:\Users\Username\Downloads\Testdataextraction\Throw it in'
for file in glob(os.path.join(path, '*.log')):
with open(file) as logfile:
for i, line in enumerate(map(str.strip, logfile), 1):
if p.search(line) is not None:
print(f'File = {file}, Line = {i}, Data = {line}')
Разве вы не хотели бы также напечатать имя файла (файлов), в котором наблюдался образец?