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

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

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

python parsing scripting ftp ftplib
8个回答
9
投票

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


8
投票

这个最佳答案

您可能想使用

ftp.nlst()
而不是
ftp.retrlines()
。它会给你你想要的。

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

系统管理进程的生成器

在他现在著名的评论《系统程序员的生成器技巧简介》中,David M. Beazley 给出了很多方法,用 wuick 和可重用的代码来回答此类数据问题。 EG:

# 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)

好吧,这在这里可能并不明显,但对于大型批处理脚本来说,这很好:-)


1
投票

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

“文件名”列表将是文件名列表。


1
投票
ftplib.FTP.nlst()

对您不起作用吗?我刚刚检查过,它仅返回给定目录中的文件名称。


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:])



1
投票
MLSD

命令,那么请参阅

that
答案中的“单目录案例”部分。 使用

ftpd

类的实例(例如

FTPDirectory
),在正确的文件夹中调用其
.getdata
方法并连接
ftplib.FTP
实例,然后您可以:

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



0
投票

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

注释 - 

    这里我假设您想要程序中的数据(作为列表),而不是控制台上的数据。
  1. each_file_detail 是程序生成的每一行。
  2. ''.join(each_file.split())
  3. 将多个空格替换为 1 个空格。


0
投票

def ftp_login(): """ Future FTP stuff """ import os from ftplib import FTP ftp = FTP() ftp.connect('phone', 2221) ftp.login('android', 'android') print("ftp.getwelcome():", ftp.getwelcome()) all_files = [] def walk(suffix, all): """ walk the path """ files = [] ftp.dir(suffix, files.append) # callback = files.append(line) # Filename could be any position on line so can't use line[52:] below # dr-x------ 3 user group 0 Aug 27 16:32 Compilations for f in files: line = ' '.join(f.split()) # compress multiple whitespace to one space parts = line.split() # split on one space size = parts[4] # Date format is either: MMM DD hh:mm or MMM DD YYYY or MMM DD YYYY date3 = parts[7] + " " # doesn't matter if the size is same as YEAR # No shortcut ' '.join(parts[8:]) - name could have had double space name = f.split(date3)[1] if f.startswith("d"): # directory? new_suffix = suffix + name + os.sep walk(new_suffix, all) # back down the rabbit hole else: # /path/to/filename.ext <SIZE> all.append(suffix + name + " <" + size.strip() + ">") walk(os.sep, all_files) # 41 seconds print("len(all_files):", len(all_files)) # 4,074 files incl 163 + 289 subdirs

输出:

ftp.getwelcome(): 220 Service ready for new user. len(all_files): 4074 /Compilations/Greatest Hits of the 80’s [Disc #3 of 3]/3-12 Poison.wav <47480228> /Compilations/Greatest Hits of the 80’s [Disc #3 of 3]/3-12 Poison.mp3 <7343013> /Compilations/Greatest Hits of the 80’s [Disc #3 of 3]/3-12 Poison.flac <31112653> /Compilations/Greatest Hits of the 80’s [Disc #3 of 3]/3-12 Poison.oga <8075357> /Compilations/Greatest Hits of the 80’s [Disc #3 of 3]/3-12 Poison.m4a <7662899> /Compilations/Don't Let Me Be Misunderstood/07 House Of The Rising Sun (Quasimot.m4a <8015709> /Compilations/Don't Let Me Be Misunderstood/01 Don't Let Me Be Misunderstood.m4a <33668167> /Compilations/Don't Let Me Be Misunderstood/03 You're My Everything.m4a <12505304> /Compilations/Don't Let Me Be Misunderstood/02 Gloria.m4a <8115224> /Compilations/Don't Let Me Be Misunderstood/04 Black Pot.m4a <14617541>

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