如何解析文件列表以获取Python中的文件名?

时间:2008-10-26 07:42:17

标签: python parsing scripting ftp ftplib

所以我想说我正在使用Python的ftplib从FTP服务器中检索日志文件列表。我如何解析该文件列表以获取列表中的文件名(最后一列)?请参阅上面的链接,例如输出。

7 个答案:

答案 0 :(得分:9)

使用retrlines()可能不是最好的想法,因为它只是打印到控制台,所以你必须做一些棘手的事情来获得输出。一个可能更好的选择是使用nlst()方法,它返回你想要的东西:文件名列表。

答案 1 :(得分:6)

这个最佳答案

您可能希望使用ftp.nlst()代替ftp.retrlines()。它会给你你想要的东西。

如果你不能,请阅读以下内容:

系统管理员进程的生成器

在他现在着名的评论Generator Tricks For Systems Programmers An Introduction中,David M. Beazley用wuick和可重复使用的代码回答了这类数据问题。

E.G:

# empty list that will receive all the log entry
log = [] 
# we pass a callback function bypass the print_line that would be called by retrlines
# we do that only because we cannot use something better than retrlines
ftp.retrlines('LIST', callback=log.append)
# we use rsplit because it more efficient in our case if we have a big file
files = (line.rsplit(None, 1)[1] for line in log)
# get you file list
files_list = list(files)

为什么我们不立即生成列表?

嗯,这是因为这样做可以提供很大的灵活性:您可以应用任何中间生成器来过滤文件,然后再将其转换为files_list:它就像管道,添加一行,添加流程而不会过热(因为它是发电机)。如果你摆脱retrlines,它仍然有效甚至更好,因为你甚至不会存储列表一次。

编辑:好吧,我读到了对另一个答案的评论,并且说如果名称中有任何空格,这将不起作用。

很酷,这将说明为什么这种方法很方便。如果您想在流程中更改某些内容,只需更改一行即可。交换:

files = (line.rsplit(None, 1)[1] for line in log)

# join split the line, get all the item from the field 8 then join them
files = (' '.join(line.split()[8:]) for line in log)

好的,这在这里可能并不明显,但对于庞大的批处理脚本,它很不错: - )

答案 2 :(得分:1)

顺便说一句,如果由于某种原因你使用retrlines(),那么稍微不那么优化的方法是将函数作为第二个参数传递给retrlines();它将被调用列表中的每个项目。所以这样的事情(假设你有一个名为'ftp'的FTP对象)也会起作用:

filenames = []
ftp.retrlines('LIST', lambda line: filenames.append(line.split()[-1]))

列表'filenames'将是文件名列表。

答案 3 :(得分:1)

由于输出中的每个文件名都在同一列开始,所以您只需要在第一行获取点的位置:

  

drwxrwsr-x 5 ftp-usr pdmaint 1536 Mar 20 09:48 .

然后使用该点的位置作为起始索引,将文件名切出其他行。

由于点是该行的最后一个字符,因此可以使用行的长度减去1作为索引。所以最终的代码是这样的:

lines = ftp.retrlines('LIST')
lines = lines.split("\n") # This should split the string into an array of lines

filename_index = len(lines[0]) - 1
files = []

for line in lines:
    files.append(line[filename_index:])

答案 4 :(得分:1)

ftplib.FTP.nlst()有什么理由不适合你吗?我刚检查过,它只返回给定目录中文件的名称。

答案 5 :(得分:1)

如果FTP服务器支持MLSD命令,请参阅that answer中的“单一目录案例”部分。

使用ftpd类的实例(比如说FTPDirectory),在正确的文件夹中调用带有.getdata实例的ftplib.FTP方法,然后您可以:

directory_filenames= [ftpfile.name for ftpfile in ftpd.files]

答案 6 :(得分:0)

我相信它应该适合你。

file_name_list = [' '.join(each_file.split()).split()[-1] for each_file_detail in file_list_from_log]

注意 -

  1. 这里我假设你想要程序中的数据(如列表),而不是控制台上。

  2. each_file_detail是程序生成的每一行。

  3. ''。join(each_file.split())

  4. 用1个空格替换多个空格。