গ্লোব.glob মডিউলটি ব্যবহার করে আমি কীভাবে সাব-ফোল্ডারগুলি অনুসন্ধান করতে পারি?


107

আমি একটি ফোল্ডারে সাবফোল্ডারগুলির একটি সিরিজ খুলতে এবং কিছু পাঠ্য ফাইলগুলি খুঁজে পেতে এবং টেক্সট ফাইলগুলির কয়েকটি লাইন মুদ্রণ করতে চাই। আমি এটি ব্যবহার করছি:

configfiles = glob.glob('C:/Users/sam/Desktop/file1/*.txt')

তবে এটি সাবফোল্ডারগুলিতেও অ্যাক্সেস করতে পারে না। কেউ কি জানেন যে আমি কীভাবে সাবফোল্ডারগুলিতে অ্যাক্সেস করতে একই কমান্ডটি ব্যবহার করতে পারি?


উত্তর:


163

পাইথন 3.5 এবং নতুনতে নতুন পুনরাবিপন্ন **/কার্যকারিতা ব্যবহার করুন :

configfiles = glob.glob('C:/Users/sam/Desktop/file1/**/*.txt', recursive=True)

কখন recursiveসেট করা হয়, **তারপরে একটি পাথ বিভাজক 0 বা আরও সাব-ডাইরেক্টরিয়ের সাথে মেলে।

পূর্ববর্তী পাইথন সংস্করণগুলিতে glob.glob()সাব ডাইরেক্টরিগুলিতে পুনরাবৃত্তভাবে ফাইল তালিকাবদ্ধ করতে পারে না।

os.walk()সেক্ষেত্রে আমি এর fnmatch.filter()পরিবর্তে একত্রিত ব্যবহার করব :

import os
import fnmatch

path = 'C:/Users/sam/Desktop/file1'

configfiles = [os.path.join(dirpath, f)
    for dirpath, dirnames, files in os.walk(path)
    for f in fnmatch.filter(files, '*.txt')]

এটি আপনার ডিরেক্টরিগুলি পুনরাবৃত্তভাবে চলবে এবং সমস্ত পরম পথের নামগুলি মেলানো .txtফাইলগুলিতে ফিরে আসবে । এই নির্দিষ্ট ক্ষেত্রে fnmatch.filter()ওভারকিল হতে পারে, আপনি একটি .endswith()পরীক্ষাও ব্যবহার করতে পারেন :

import os

path = 'C:/Users/sam/Desktop/file1'

configfiles = [os.path.join(dirpath, f)
    for dirpath, dirnames, files in os.walk(path)
    for f in files if f.endswith('.txt')]

3
আমি দেখতে পাচ্ছি: glob.glob ('/ ডিরেক্টরিতে যাওয়ার পথ / * / *। Txt ") আমার জন্য কাজ করছে This এটি মূলত ইউনিক্স শেল নিয়মটি ব্যবহার করছে
সূর্য

7
@ ব্যবহারকারী 123: ডিরেক্টরিগুলি পুনরাবৃত্তির সাথে তালিকাবদ্ধ করে না । আপনি সমস্ত পাঠ্য ফাইলকে এক স্তর গভীর করে তালিকাভুক্ত করছেন , তবে পরবর্তী উপ-ডিরেক্টরিতে বা সরাসরি সরাসরি নয় path to directory
মার্টিজন পিটারস

1
এটি সম্পূর্ণরূপে সম্পর্কিত নয়, তবে কার্যকারিতার recursive=Falseসাথে একসাথে সেট করা কেন **/কেবল প্রদত্ত ফোল্ডারে ফাইলগুলির তালিকা সরবরাহ করে না, বরং তার বাচ্চাদের মধ্যে?
Dr_Zaszuś

@ ডাঃ জাজজুś: দুঃখিত? বর্তমান কার্যনির্বাহী ডিরেক্টরিতে ডিরেক্টরি নামের**/ একটি তালিকা দেয় কারণ প্যাটার্নটি শেষ হয় এবং আপনার সাথে মূলত একটি ডাবল থাকে , ঠিক কম দক্ষ হিসাবে ঠিক একই সাথে মিল থাকে । /recursive=False**/
মার্টিজন পিটারস

@ Dr_Zaszuś: */*আপনার যদি সমস্ত উপ-ডিরেক্টরিতে সমস্ত ফাইলের প্রয়োজন হয় তা ব্যবহার করুন ।
মার্টিজন পিটারস

22

তাত্ক্ষণিক সাব-ডিরেক্টরিতে ফাইলগুলি সন্ধান করতে:

configfiles = glob.glob(r'C:\Users\sam\Desktop\*\*.txt')

একটি পুনরাবৃত্ত সংস্করণ যা সমস্ত উপ-ডিরেক্টরিকে অতিক্রম করে, আপনি পাইথন 3.5 থেকে ব্যবহার করতে **এবং পাস করতে পারেন :recursive=True

configfiles = glob.glob(r'C:\Users\sam\Desktop\**\*.txt', recursive=True)

উভয় ফাংশন কল রিটার্ন তালিকা। আপনি glob.iglob()এক এক করে পাথ ফেরত দিতে ব্যবহার করতে পারেন। বা ব্যবহার করুনpathlib :

from pathlib import Path

path = Path(r'C:\Users\sam\Desktop')
txt_files_only_subdirs = path.glob('*/*.txt')
txt_files_all_recursively = path.rglob('*.txt') # including the current dir

উভয় পদ্ধতিই পুনরাবৃত্তির ফিরিয়ে দেয় (আপনি একের পর এক পথ পেতে পারেন)।


হ্যাঁ, আমি বুঝতে পেরেছি; তবে আমি glob()ডিরেক্টরিতে নিদর্শনগুলি সমর্থন করার আশা করিনি ।
মার্টিজন পিটারস

মন্তব্য মুছে ফেলা হয়েছে, আমি এখন দেখছি যে এটি ভুল ধারণা দিয়েছে; এছাড়াও, **প্যাচটিতে পুনরাবৃত্তির ক্ষেত্রে ডকুমেন্টেশন আপডেট অন্তর্ভুক্ত রয়েছে । কিন্তু জন্য **কাজ জন্য, আপনাকে আছে সেট করতে recursion=True, সুইচ BTW।
মার্টিজন পিটারস

20

এই বিষয় নিয়ে অনেক বিভ্রান্তি রয়েছে। আমি এটি পরিষ্কার করতে পারি কিনা তা আমাকে দেখতে দিন (পাইথন ৩. 3.):

  1. glob.glob('*.txt') :বর্তমান ডিরেক্টরিতে '.txt' এ শেষ হওয়া সমস্ত ফাইলের সাথে মেলে
  2. glob.glob('*/*.txt') :1 হিসাবে একই
  3. glob.glob('**/*.txt') :কেবলমাত্র তাত্ক্ষণিক সাব-ডিরেক্টরিতে '.txt' এ শেষ হওয়া সমস্ত ফাইলের সাথে মেলে , তবে বর্তমান ডিরেক্টরিতে নয়
  4. glob.glob('*.txt',recursive=True) :1 হিসাবে একই
  5. glob.glob('*/*.txt',recursive=True) :3 হিসাবে একই
  6. glob.glob('**/*.txt',recursive=True):বর্তমান ডিরেক্টরিতে এবং সমস্ত উপ-ডিরেক্টরিতে '.txt' এ শেষ হওয়া সমস্ত ফাইলের সাথে মেলে

তাই সর্বদা নির্দিষ্ট করা ভাল recursive=True.


1
এটি শীর্ষ উত্তর হতে হবে!
অভীক সরকার

17

Glob2 প্যাকেজ বন্য কার্ড সমর্থন করে এবং যুক্তিসঙ্গতভাবে দ্রুত

code = '''
import glob2
glob2.glob("files/*/**")
'''
timeit.timeit(code, number=1)

আমার ল্যাপটপে > 60,000 ফাইল পাথের সাথে মিলতে প্রায় 2 সেকেন্ড সময় লাগে ।



4

এখানে একটি অভিযোজিত সংস্করণ যা glob.globব্যবহার না করে কার্যকারিতার মতো সক্ষম করে glob2

def find_files(directory, pattern='*'):
    if not os.path.exists(directory):
        raise ValueError("Directory not found {}".format(directory))

    matches = []
    for root, dirnames, filenames in os.walk(directory):
        for filename in filenames:
            full_path = os.path.join(root, filename)
            if fnmatch.filter([full_path], pattern):
                matches.append(os.path.join(root, filename))
    return matches

সুতরাং আপনার যদি নিম্নলিখিত dir কাঠামো আছে

tests/files
├── a0
   ├── a0.txt
   ├── a0.yaml
   └── b0
       ├── b0.yaml
       └── b00.yaml
└── a1

আপনি এরকম কিছু করতে পারেন

files = utils.find_files('tests/files','**/b0/b*.yaml')
> ['tests/files/a0/b0/b0.yaml', 'tests/files/a0/b0/b00.yaml']

fnmatchশুধুমাত্র ফাইলের পরিবর্তে পুরো ফাইলের নামেই খুব বেশি প্যাটার্ন মেলে।


2

configfiles = glob.glob('C:/Users/sam/Desktop/**/*.txt")

সমস্ত ক্ষেত্রে ব্যবহার করে না, পরিবর্তে গ্লোব 2 ব্যবহার করুন

configfiles = glob2.glob('C:/Users/sam/Desktop/**/*.txt")

2

আপনি যদি glob2 প্যাকেজ ইনস্টল করতে পারেন ...

import glob2
filenames = glob2.glob("C:\\top_directory\\**\\*.ext")  # Where ext is a specific file extension
folders = glob2.glob("C:\\top_directory\\**\\")

সমস্ত ফাইলের নাম এবং ফোল্ডার:

all_ff = glob2.glob("C:\\top_directory\\**\\**")  

2

আপনি যদি পাইথন ৩.৪++ চালাচ্ছেন তবে আপনি pathlibমডিউলটি ব্যবহার করতে পারেন । Path.glob()পদ্ধতি সমর্থন **প্যাটার্ন, যার মানে "এই ডিরেক্টরি ও সমস্ত সাব-, যাও recursively"। এটি Pathসমস্ত মিলে যাওয়া ফাইলের জন্য একটি জেনারেটর উত্পাদনকারী বস্তু প্রদান করে।

from pathlib import Path
configfiles = Path("C:/Users/sam/Desktop/file1/").glob("**/*.txt")

0

মার্টিজন দ্বারা চিহ্নিত হিসাবে, গ্লোব কেবল **পাইথন 3.5 তে চালু হওয়া অপারেটরের মাধ্যমে এটি করতে পারে । যেহেতু ওপি স্পষ্টতই গ্লোব মডিউলটির জন্য জিজ্ঞাসা করেছে, নিম্নলিখিতগুলি একইভাবে আচরণ করে এমন একটি অলস মূল্যায়ন পুনরুদ্ধার ফিরিয়ে দেবে

import os, glob, itertools

configfiles = itertools.chain.from_iterable(glob.iglob(os.path.join(root,'*.txt'))
                         for root, dirs, files in os.walk('C:/Users/sam/Desktop/file1/'))

দ্রষ্টব্য যে আপনি configfilesএই পদ্ধতির মধ্যে কেবল একবারে পুনরাবৃত্তি করতে পারেন । আপনার যদি কনফিগার ফাইলগুলির বাস্তব তালিকা প্রয়োজন হয় যা একাধিক ক্রিয়াকলাপে ব্যবহার করা যেতে পারে আপনাকে এটি ব্যবহার করে স্পষ্ট করে তৈরি করতে হবে list(configfiles)


0

কমান্ডটি rglobআপনার ডিরেক্টরি কাঠামোর গভীরতম উপ-স্তরের নিচে অসীম পুনরাবৃত্তি করবে। আপনি যদি কেবল একটি স্তর গভীর করতে চান তবে তবে এটি ব্যবহার করবেন না।

আমি বুঝতে পারি যে ওপি গ্লোব্ল্লো.glob ব্যবহারের বিষয়ে কথা বলছিল। আমি বিশ্বাস করি এটি এর উদ্দেশ্যটির উত্তর দেয়, তবে এটি সমস্ত সাবফোল্ডারকে পুনরাবৃত্তভাবে অনুসন্ধান করা।

rglobফাংশন সম্প্রতি একটি ডাটা প্রসেসিং অ্যালগরিদম যা ডেটা পড়ার ক্রম জন্য একটি নির্দিষ্ট ধৃষ্টতা ফোল্ডারে কাঠামো ব্যবহার করছিলেন গতি হিসাবে এতে 100 গুণ বৃদ্ধি উত্পাদিত। তবে, rglobআমরা নির্দিষ্ট অভিভাবক ডিরেক্টরিতে বা তার নীচে সমস্ত ফাইলের মাধ্যমে একবার একক স্ক্যান করতে সক্ষম হয়েছিলাম, তাদের নামগুলি একটি তালিকার (দশ লক্ষেরও বেশি ফাইলের মধ্যে) সংরক্ষণ করুন, তারপরে কোন তালিকাতে আমাদের কোন ফাইলগুলি খুলতে হবে তা নির্ধারণ করতে সেই তালিকাটি ব্যবহার করুন ভবিষ্যতে ফাইল নামকরণ কনভেনশনগুলির ভিত্তিতে কেবলমাত্র বনাম কোন ফোল্ডারে ছিলেন সেগুলি নির্দেশ করুন।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.