[使用Python3从日志文件中提取所有JavaScript文件名

问题描述 投票:0回答:2

我是Python3的新手,正在使用文本文件。我试图从以JavaScript(.js)扩展名结尾的日志文件中提取所有文件名。该文件还包含其他文件扩展名。我只想返回文件名而不返回路径,按字母顺序对输出进行排序,并显示uniuqe值,因为日志条目中有重复项。

日志文件中的示例为:

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.jsjquery.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的行,但我不知道如何提取其余部分。我尝试使用正则表达式进行匹配,但是由于使用它也是新手,因此并未成功。任何帮助将不胜感激。

python-3.x text-extraction
2个回答
1
投票

这是另一个纯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的索引,向左移动。

使用这两个索引对行进行切片以提供文件名。如果未找到.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

1
投票

这可以用正则表达式来完成,但是我想我只给出一个python解决方案。

我采用的方法是根据OS路径字符/分割每一行。对于Windows操作系统,它将为'\'(因此,如果您希望它是跨平台的,请记住这一点)。这给出了一个列表。然后,我们在列表中的每个元素中搜索“ .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

© www.soinside.com 2019 - 2024. All rights reserved.