আমার কাছে একটি ফাইল রয়েছে যা প্রতিটি ব্যবহারকারীর মেশিনে আলাদা জায়গায় থাকতে পারে। ফাইলটির জন্য কোনও অনুসন্ধান কার্যকর করার কোনও উপায় আছে? এমন কোনও উপায়ে যা আমি অনুসন্ধান করতে ফাইলের নাম এবং ডিরেক্টরি ট্রিটি পাস করতে পারি?
আমার কাছে একটি ফাইল রয়েছে যা প্রতিটি ব্যবহারকারীর মেশিনে আলাদা জায়গায় থাকতে পারে। ফাইলটির জন্য কোনও অনুসন্ধান কার্যকর করার কোনও উপায় আছে? এমন কোনও উপায়ে যা আমি অনুসন্ধান করতে ফাইলের নাম এবং ডিরেক্টরি ট্রিটি পাস করতে পারি?
উত্তর:
os.walk এর উত্তর, এটি প্রথম মিল খুঁজে পাবে:
import os
def find(name, path):
for root, dirs, files in os.walk(path):
if name in files:
return os.path.join(root, name)
এবং এটি সমস্ত মিল খুঁজে পাবেন:
def find_all(name, path):
result = []
for root, dirs, files in os.walk(path):
if name in files:
result.append(os.path.join(root, name))
return result
এবং এটি একটি প্যাটার্নের সাথে মিলবে:
import os, fnmatch
def find(pattern, path):
result = []
for root, dirs, files in os.walk(path):
for name in files:
if fnmatch.fnmatch(name, pattern):
result.append(os.path.join(root, name))
return result
find('*.txt', '/path/to/dir')
if name in file or name in dirs
for name in files:ব্যর্থ হবে । (আমার জীবনের এক ঘন্টা আমি ফিরে চাই ;-) কিছুটা অগোছালো সমাধান হ'লsuper-photo.jpgsuper-photo.JPGif str.lower(name) in [x.lower() for x in files]
আমি একটি সংস্করণ ব্যবহার করেছি os.walkএবং বৃহত্তর ডিরেক্টরিতে প্রায় 3.5 সেকেন্ডের কাছাকাছি সময় পেয়েছি। আমি কোনও দুর্দান্ত উন্নতি না করে দুটি এলোমেলো সমাধান চেষ্টা করেছি, ঠিক তখনি করেছি:
paths = [line[2:] for line in subprocess.check_output("find . -iname '*.txt'", shell=True).splitlines()]
এটি কেবল পসিক্স-এর মধ্যেই আমি 0.25 সেকেন্ড পেয়েছি।
এ থেকে, আমি বিশ্বাস করি যে প্ল্যাটফর্ম-স্বতন্ত্র উপায়ে পুরো অনুসন্ধানকে প্রচুর অনুকূলিতকরণ করা সম্পূর্ণভাবে সম্ভব, তবে এখান থেকেই আমি গবেষণাটি থামিয়ে দিয়েছি।
আপনি যদি উবুন্টুতে পাইথন ব্যবহার করে থাকেন এবং আপনি কেবল উবুন্টুতে এটির কাজ করতে চান তবে এটি টার্মিনালের locateপ্রোগ্রামটির মতো ব্যবহার is
import subprocess
def find_files(file_name):
command = ['locate', file_name]
output = subprocess.Popen(command, stdout=subprocess.PIPE).communicate()[0]
output = output.decode()
search_results = output.split('\n')
return search_results
search_resultsএকটি হল listপরম ফাইল পাথ করুন। এটি উপরের পদ্ধতিগুলির তুলনায় 10,000 গুণ বেশি গতিযুক্ত এবং একটি অনুসন্ধানের জন্য আমি এটি ~ 72,000 গুণ বেশি দ্রুত করেছি।
পাইথন ৩.৪ বা তার চেয়েও নতুন আপনি পুনরাবৃত্ত গ্লোব্বিং করতে পাথলিব ব্যবহার করতে পারেন:
>>> import pathlib
>>> sorted(pathlib.Path('.').glob('**/*.py'))
[PosixPath('build/lib/pathlib.py'),
PosixPath('docs/conf.py'),
PosixPath('pathlib.py'),
PosixPath('setup.py'),
PosixPath('test_pathlib.py')]
তথ্যসূত্র: https://docs.python.org/3/library/pathlib.html#pathlib.Path.glob
পাইথন 3.5 বা আরও নতুনতে আপনি এরকম পুনরাবৃত্ত গ্লোববিংও করতে পারেন:
>>> import glob
>>> glob.glob('**/*.txt', recursive=True)
['2.txt', 'sub/3.txt']
তথ্যসূত্র: https://docs.python.org/3/library/glob.html#glob.glob
দ্রুত, ওএস-স্বাধীন অনুসন্ধানের জন্য, ব্যবহার করুন scandir
https://github.com/benhoyt/scandir/#readme
কেন তা বিশদ জানতে http://bugs.python.org/issue11406 পড়ুন ।
scandir.walk()@ নাদিয়ার উত্তর প্রতি ব্যবহার করুন । মনে রাখবেন যে আপনি যদি পাইথন 3.5+ ব্যবহার করেন os.walk()তবে এর scandir.walk()স্পিডআপগুলি ইতিমধ্যে রয়েছে। এছাড়াও, পিইপি 471 সম্ভবত এই ইস্যুটির চেয়ে তথ্যের জন্য পড়ার জন্য আরও ভাল নথি।
আপনি যদি পাইথন 2 এর সাথে কাজ করছেন তবে স্ব-উল্লেখকারী সিমলিংকের কারণে উইন্ডোগুলিতে আপনার অসীম পুনরাবৃত্তি হতে সমস্যা হয়।
এই স্ক্রিপ্টটি সেগুলি অনুসরণ করা এড়াবে। মনে রাখবেন এটি উইন্ডো-নির্দিষ্ট !
import os
from scandir import scandir
import ctypes
def is_sym_link(path):
# http://stackoverflow.com/a/35915819
FILE_ATTRIBUTE_REPARSE_POINT = 0x0400
return os.path.isdir(path) and (ctypes.windll.kernel32.GetFileAttributesW(unicode(path)) & FILE_ATTRIBUTE_REPARSE_POINT)
def find(base, filenames):
hits = []
def find_in_dir_subdir(direc):
content = scandir(direc)
for entry in content:
if entry.name in filenames:
hits.append(os.path.join(direc, entry.name))
elif entry.is_dir() and not is_sym_link(os.path.join(direc, entry.name)):
try:
find_in_dir_subdir(os.path.join(direc, entry.name))
except UnicodeDecodeError:
print "Could not resolve " + os.path.join(direc, entry.name)
continue
if not os.path.exists(base):
return
else:
find_in_dir_subdir(base)
return hits
এটি সমস্ত পাথের সাথে একটি তালিকা ফেরত দেয় যা ফাইলের তালিকা তালিকার ফাইলগুলিতে নির্দেশ করে। ব্যবহার:
find("C:\\", ["file1.abc", "file2.abc", "file3.abc", "file4.abc", "file5.abc"])
নীচে আমরা প্রথম ম্যাচ এবং সমস্ত ম্যাচের মধ্যে স্যুইচ করতে একটি বুলিয়ান "প্রথম" যুক্তি ব্যবহার করি (একটি ডিফল্ট যা "সন্ধান করুন-নাম ফাইল" এর সমতুল্য):
import os
def find(root, file, first=False):
for d, subD, f in os.walk(root):
if file in f:
print("{0} : {1}".format(file, d))
if first == True:
break
উত্তরটি বিদ্যমানগুলির সাথে খুব মিল, তবে কিছুটা অনুকূলিত হয়েছে।
সুতরাং আপনি প্যাটার্ন অনুসারে কোনও ফাইল বা ফোল্ডার খুঁজে পেতে পারেন:
def iter_all(pattern, path):
return (
os.path.join(root, entry)
for root, dirs, files in os.walk(path)
for entry in dirs + files
if pattern.match(entry)
)
হয় সাবস্ট্রিং দ্বারা:
def iter_all(substring, path):
return (
os.path.join(root, entry)
for root, dirs, files in os.walk(path)
for entry in dirs + files
if substring in entry
)
বা একটি শিকারী ব্যবহার:
def iter_all(predicate, path):
return (
os.path.join(root, entry)
for root, dirs, files in os.walk(path)
for entry in dirs + files
if predicate(entry)
)
কেবল ফাইল বা কেবল ফোল্ডার অনুসন্ধান করতে - আপনার প্রয়োজনীয়তার উপর নির্ভর করে "ডায়ার + ফাইল" প্রতিস্থাপন করুন, উদাহরণস্বরূপ, কেবল "ডায়ার" বা কেবল "ফাইল" দিয়ে।
শুভেচ্ছা।
আমি উবুন্টু 20.04 এলটিএস থেকে আপডেট না হওয়া পর্যন্ত সরোসের উত্তর আমার পক্ষে কাজ করেছে। আমি তার কোডে সামান্য পরিবর্তন এনেছি এটি সর্বশেষতম উবুন্টু মুক্তির কাজ করে।
import subprocess
def find_files(file_name):
file_name = 'chromedriver'
command = ['locate'+ ' ' + file_name]
output = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True).communicate()[0]
output = output.decode()
search_results = output.split('\n')
return search_results