Извлечение всех JavaScript имен файлов из файла журнала с использованием Python3 - PullRequest
1 голос
/ 14 марта 2020

Я новичок в Python3 и работаю с текстовыми файлами. Я пытаюсь извлечь все имена файлов из файла журнала, которые заканчиваются JavaScript (. js) расширениями. Файл также содержит другие расширения. Я хочу вернуть только имя файла, а не путь, отсортировать вывод по алфавиту и отобразить уникальные значения, поскольку в записях журнала есть повторы.

Примеры из файла журнала:

72.133.47.242 - - [25 / Apr / 2013: 15: 45: 28 -0700] "GET /include/jquery.js HTTP / 1.1 "200 25139

22.133.47.242 - - [25 / Apr / 2013: 15: 45: 28 -0700]" GET /include/jquery.jshowoff.js HTTP / 1.1 "200 25139

В этом случае я просто хочу вернуть jquery. js и jquery .jshowoff. js, а не HTTP запрос и другие данные журнала.

Это мой код:

filepath = '/home/user/Documents/access_log.txt'
with open(filepath, 'r') as access_log:
    contents = access_log.readlines()
    for line in contents:
        if ".js" in line:
            print(line)

Мой вывод возвращает только строки, которые содержат . js, но я не знаю, как извлечь остальное. Я пытался использовать регулярные выражения для соответствия, но не увенчался успехом, так как я также новичок в использовании этого. Любая помощь будет принята с благодарностью.

Ответы [ 2 ]

2 голосов
/ 14 марта 2020

Вот еще одно чисто-Python решение, использующее в качестве ввода следующие данные: logfile.txt:

72.133.47.242 - - [25/Apr/2013:15:45:28 -0700] "GET /include/jquery.js HTTP/1.1" 200 25139
22.133.47.242 - - [25/Apr/2013:15:45:28 -0700] "GET /include/jquery.jshowoff.js HTTP/1.1" 200 25139
72.133.47.242 - - [25/Apr/2013:15:45:28 -0700] "GET /2468.js HTTP/1.1" 200 25139
72.133.47.242 - - [25/Apr/2013:15:45:28 -0700] "GET /Abcd.js HTTP/1.1" 200 25139
22.133.47.242 - - [25/Apr/2013:15:45:28 -0700] "GET /abcd.js HTTP/1.1" 200 25139
72.133.47.242 - - [25/Apr/2013:15:45:28 -0700] "GET /aBcd.js HTTP/1.1" 200 25139
22.133.47.242 - - [25/Apr/2013:15:45:28 -0700] "GET / asd.js HTTP/1.1" 200 25139
72.133.47.242 - - [25/Apr/2013:15:45:28 -0700] "GET /include/index.html HTTP/1.1" 200 25139
72.133.47.242 - - [25/Apr/2013:15:45:28 -0700] "GET /include/login.jsp HTTP/1.1" 200 25139

Все имена JavaScript хранятся в set, так как вы хотите только уникальные ценности. Перед печатью они сортируются в алфавитном порядке.

Он перебирает каждую строку, находит индекс первого .js, начиная с конца строки, затем находит индекс первого /, начиная с откуда он нашел .js, направляясь влево.

Строка разрезана с использованием этих 2 индексов, чтобы дать нам имя файла. Если .js не найден, rfind возвращает -1, что не имеет значения, потому что в конце мы проверяем, заканчивается ли имя файла .js, прежде чем добавить его в set. Вы можете использовать rindex, но вам нужно будет обработать ValueError для строк, которые не имеют .js.

filenames = set()

with open(r"C:\Users\Old Joe\Desktop\logfile.txt") as f:
    for line in f:
        end = line.rfind(".js") + 3 # 3 = len(".js")
        start = line.rfind("/", 0, end) + 1 # 1 = len("/")
        filename = line[start:end]
        if filename.endswith(".js"):
            filenames.add(filename)


for filename in sorted(filenames, key=str.lower):
    print(filename)

Вывод:

 asd.js
2468.js
aBcd.js
abcd.js
Abcd.js
jquery.js
jquery.jshowoff.js
login.js
2 голосов
/ 14 марта 2020

Это можно сделать с помощью регулярных выражений, но я решил, что дам всего лишь python решение.

Подход, который я выбрал, состоял в том, чтобы разбить каждую строку на основе символа пути ОС: /. Для Windows OS это будет '\' (имейте это в виду, если вы хотите, чтобы это было кроссплатформенным). Это дает список. Затем мы ищем каждый элемент в списке для «. js». Пространство всегда должно быть там. Элемент с именем файла будет иметь дополнительные элементы после имени файла, поэтому просто разбейте на «. js» и сохраните только первый элемент этого разбиения. Я также прокомментировал эти фрагменты в коде.

with open(filepath, 'r') as access_log:
    contents = access_log.readlines()
    log_filenames = []
    for line in contents:
        # log_filenames on mac/linux will use / so split on that then search for filename
        for fragment in line.split('/'):
            if ".js " in fragment:
                # there will be text after .js, so remove it
                frags = fragment.split('.js ')
                # split on ".js " will give us the base filename as first element of list
                basename = frags[0]
                filename = basename + '.js'
                log_filenames.append(filename)
    # get unique values
    log_filenames = list(set(log_filenames))
    # sort
    log_filenames.sort()
    print('\n'.join(log_filenames))

Выходы:

jquery.js
jquery.jshowoff.js

Примечание: при получении уникальных значений я преобразовал set обратно в list на всякий случай вы не привыкли работать с set s.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...