كيف أقوم بتحليل قائمة الملفات للحصول على أسماء الملفات فقط في بايثون؟

StackOverflow https://stackoverflow.com/questions/237699

سؤال

لنفترض أنني أستخدم لغة بايثون ftplib لاسترداد قائمة ملفات السجل من خادم FTP.كيف يمكنني تحليل قائمة الملفات هذه للحصول على أسماء الملفات فقط (العمود الأخير) داخل القائمة؟انظر الرابط أعلاه على سبيل المثال الإخراج.

هل كانت مفيدة؟

المحلول

وعن طريق retrlines () ربما ليست أفضل فكرة هناك، لأنه يطبع فقط إلى وحدة التحكم وذلك عليك أن تفعل أشياء صعبة للحصول حتى في ذلك الانتاج. ومن شأن الرهان على الأرجح أفضل أن يكون لاستخدام أسلوب ضريبة دعم العمالة الوطنية ()، والتي ترجع بالضبط ما تريد: قائمة أسماء الملفات

نصائح أخرى

هذا أفضل إجابة

وأنت قد تحتاج إلى استخدام ftp.nlst() بدلا من ftp.retrlines(). وسوف تعطيك بالضبط ما تريد.

إذا كنت لا تستطيع قراءة ما يلي:

مولدات لعمليات مسؤول النظام

في بلده الآن الشهير الاستعراض، مولد الخدع لنظم المبرمجين مقدمة ، ديفيد M. بيزلي يعطي الكثير من ريسيبيس للرد على هذا النوع من المشاكل البيانات مع wuick ورمز قابلة لإعادة الاستخدام.

ومنها مثلا:

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

وطيب، وهذا قد لا يكون واضحا هنا، ولكن للمخطوطات عملية دفعة كبيرة، انها لطيفة: -)

وطريقة أقل قليلا الأمثل، بالمناسبة، إذا كنت عالقا باستخدام retrlines () لسبب ما، لتمرير وظيفة كما الوسيطة الثانية إلى retrlines ()؛ أنه سوف يتم استدعاؤها من أجل كل عنصر في القائمة. ذلك شيء من هذا القبيل (على افتراض لديك كائن FTP اسمه 'بروتوكول نقل الملفات') ستعمل أيضا:

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

وو'أسماء' قائمة بعد ذلك سوف تكون قائمة أسماء الملفات.

لماذا هل هناك أي سبب ftplib.FTP.nlst() لن تعمل بالنسبة لك؟لقد قمت للتو بالتحقق وهي تقوم بإرجاع أسماء الملفات الموجودة في دليل معين فقط.

وبما أن كل اسم في إخراج يبدأ في نفس العمود، كل ما عليك القيام به هو الحصول على موقف من نقطة على السطر الأول:

<اقتباس فقرة>   

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

وإذا كان يدعم خادم FTP الأمر MLSD، ثم راجع قسم "القضية دليل واحد" من <لأ href = "https://stackoverflow.com/questions/2867217/how-to-delete-files-with-a -python-النصي من واحد في بروتوكول نقل الملفات خادم والتي، هي، أقدم مما كان 7/3114477 # 3114477 "> أن الإجابة.

استخدم مثيل (ويقول ftpd) من الدرجة FTPDirectory، دعوة طريقة .getdata مع المثال ftplib.FTP متصلة في المجلد الصحيح، ثم يمكنك:

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

أعتقد أنه يجب أن يعمل من أجلك.

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

ملحوظات -

  1. أنا هنا أفترض أنك تريد البيانات الموجودة في البرنامج (كقائمة)، وليس على وحدة التحكم.

  2. every_file_detail هو كل سطر يتم إنتاجه بواسطة البرنامج.

  3. ' '.الانضمام(each_file.split())

لاستبدال مسافات متعددة بمسافة واحدة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top