উত্তর:
অন্যদের পরামর্শ হিসাবে ব্যবহার করা os.path.split
বা os.path.basename
সব ক্ষেত্রে কাজ করবে না: আপনি যদি লিনাক্সে স্ক্রিপ্টটি চালাচ্ছেন এবং একটি উইন্ডোজ-শৈলীর ক্লাসিকের প্রক্রিয়া চালানোর চেষ্টা করছেন, এটি ব্যর্থ হবে।
উইন্ডোজ পাথগুলি ব্যাকস্ল্যাশ বা ফরোয়ার্ড স্ল্যাশকে পাথ বিভাজক হিসাবে ব্যবহার করতে পারে। সুতরাং, ntpath
মডিউলটি (যা উইন্ডোজ চলাকালীন os.path এর সমান ) সমস্ত প্ল্যাটফর্মের সমস্ত (1) পাথের জন্য কাজ করবে ।
import ntpath
ntpath.basename("a/b/c")
অবশ্যই, যদি ফাইলটি একটি স্ল্যাশ দিয়ে শেষ হয়, তবে বেসনামটি খালি থাকবে, সুতরাং এটির মোকাবেলায় আপনার নিজের ফাংশনটি তৈরি করুন:
def path_leaf(path):
head, tail = ntpath.split(path)
return tail or ntpath.basename(head)
প্রতিপাদন:
>>> paths = ['a/b/c/', 'a/b/c', '\\a\\b\\c', '\\a\\b\\c\\', 'a\\b\\c',
... 'a/b/../../a/b/c/', 'a/b/../../a/b/c']
>>> [path_leaf(path) for path in paths]
['c', 'c', 'c', 'c', 'c', 'c', 'c']
(1) একটি সতর্কতা রয়েছে: লিনাক্স ফাইলের নামগুলিতে ব্যাকস্ল্যাশ থাকতে পারে । তাই লিনাক্স, r'a/b\c'
সবসময় ফাইল নির্দেশ করে b\c
যে a
, ফোল্ডার যখন Windows এ, এটা সবসময় বোঝায় c
ফাইল b
এর subfolder a
ফোল্ডার। সুতরাং যখন উভয় এগিয়ে এবং অনুন্নত স্ল্যাশ একটি পাথ ব্যবহার করা হয়, আপনি প্রয়োজন সংশ্লিষ্ট প্ল্যাটফর্ম জানেন যে এটি সঠিকভাবে ব্যাখ্যা করা পাবে। অনুশীলনে সাধারণত এটি একটি উইন্ডোজ পথ অনুমান করা নিরাপদ যেহেতু ব্যাকস্ল্যাশগুলি খুব কমই লিনাক্স ফাইলের নামগুলিতে ব্যবহৃত হয়, তবে আপনি কোড দেওয়ার সময় এটি মনে রাখবেন যাতে আপনি দুর্ঘটনাজনিত সুরক্ষা ছিদ্র তৈরি করেন না।
r'C:\path\to\file.txt'
লিনাক্স মেশিনে উইন্ডোজ স্টাইলের পাথগুলি (যেমন, ) পার্স করতে হবে তখনই আপনাকে এনটিপথ মডিউলটি ব্যবহার করতে হবে। অন্যথায়, আপনি os.path থেকে ফাংশনগুলি ব্যবহার করতে পারেন। এটি কারণ লিনাক্স সিস্টেমগুলি সাধারণত ফাইলের নামগুলিতে ব্যাকস্ল্যাশ অক্ষর ব্যবহারের অনুমতি দেয় (উত্তরে বর্ণিত হিসাবে)।
os.path.basename(os.path.normpath(path))
?
আসলে, একটি ফাংশন রয়েছে যা আপনি যা চান ঠিক তেমন ফেরত দেয়
import os
print(os.path.basename(your_path))
os.path.basename(your_path)
এই কাজ! : আমি স্ক্রিপ্ট পথ চেয়েছিলেন os.path.dirname(os.path.realpath(__file__))
এবং স্ক্রিপ্ট নাম: os.path.basename(os.path.realpath(__file__))
। ধন্যবাদ!
'C:\\temp\\bla.txt'
পরিবর্তে পেতে পারেন ।
os.path.split হ'ল ফাংশনটি আপনি সন্ধান করছেন
head, tail = os.path.split("/tmp/d/a.dat")
>>> print(tail)
a.dat
>>> print(head)
/tmp/d
import os
head, tail = os.path.split('path/to/file.exe')
লেজ আপনি চান ফাইল নাম।
বিশদ জন্য পাইথন ওএস মডিউল ডক্স দেখুন
import os
file_location = '/srv/volume1/data/eds/eds_report.csv'
file_name = os.path.basename(file_location ) #eds_report.csv
location = os.path.dirname(file_location ) #/srv/volume1/data/eds
আপনার উদাহরণে আপনাকে ফিরে আসতে ডান দিক থেকে স্ল্যাশ ফেলা করতে হবে c
:
>>> import os
>>> path = 'a/b/c/'
>>> path = path.rstrip(os.sep) # strip the slash from the right side
>>> os.path.basename(path)
'c'
দ্বিতীয় স্তর:
>>> os.path.filename(os.path.dirname(path))
'b'
আপডেট: আমি মনে করি lazyr
সঠিক উত্তর সরবরাহ করেছে। আমার কোড ইউনিক্স সিস্টেমে উইন্ডোজ জাতীয় পাথ এবং উইন্ডোজ সিস্টেমে ইউনিক্সের মতো পাথের সাথে কাজ করবে না।
r"a\b\c"
লিনাক্স বা "a/b/c"
উইন্ডোতে কাজ করবে না ।
os.path.basename(path)
শুধুমাত্র যদি কাজ করবে os.path.isfile(path)
হয় True
। অতএব path = 'a/b/c/'
কোনও বৈধ ফাইলের নাম নয় ...
os.path.basename("a/b/c/")
ফিরে আসে ""
।
lazyr
তুমি ঠিক! আমি সে সম্পর্কে ভেবে দেখিনি। এটা কি কেবল নিরাপদ হবে path = path.replace('\\', '/')
?
fname = str("C:\Windows\paint.exe").split('\\')[-1:][0]
এটি ফিরে আসবে: color.exe
আপনার পাথ বা ওএস সম্পর্কিত বিভক্ত ফাংশনের সেপ মানটি পরিবর্তন করুন।
fname = str(path).split('/')[-1]
যদি আপনার ফাইলের পথটি "/" এবং "/" দ্বারা পৃথক ডিরেক্টরিগুলি দিয়ে শেষ না হয় তবে নিম্নলিখিত কোডটি ব্যবহার করুন। যেমনটি আমরা জানি সাধারণত "/" দিয়ে পথ শেষ হয় না।
import os
path_str = "/var/www/index.html"
print(os.path.basename(path_str))
তবে কিছু ক্ষেত্রে URL গুলি "/" দিয়ে শেষ হয় তারপরে নিম্নলিখিত কোডটি ব্যবহার করুন
import os
path_str = "/home/some_str/last_str/"
split_path = path_str.rsplit("/",1)
print(os.path.basename(split_path[0]))
তবে যখন আপনার পথটি "\" দ্বারা গতিযুক্ত হয় যা আপনি উইন্ডোজ পাথগুলিতে সাধারণত দেখতে পান তবে আপনি নিম্নলিখিত কোডগুলি ব্যবহার করতে পারেন
import os
path_str = "c:\\var\www\index.html"
print(os.path.basename(path_str))
import os
path_str = "c:\\home\some_str\last_str\\"
split_path = path_str.rsplit("\\",1)
print(os.path.basename(split_path[0]))
ওএস টাইপ যাচাই করে আপনি দুটি ফাংশনে একত্রিত করতে পারেন এবং ফলাফলটি ফিরে আসতে পারেন।
এটি লিনাক্স এবং উইন্ডোগুলির পাশাপাশি স্ট্যান্ডার্ড লাইব্রেরির জন্যও কাজ করছে
paths = ['a/b/c/', 'a/b/c', '\\a\\b\\c', '\\a\\b\\c\\', 'a\\b\\c',
'a/b/../../a/b/c/', 'a/b/../../a/b/c']
def path_leaf(path):
return path.strip('/').strip('\\').split('/')[-1].split('\\')[-1]
[path_leaf(path) for path in paths]
ফলাফল:
['c', 'c', 'c', 'c', 'c', 'c', 'c']
এখানে একটি রেজেক্স-কেবল সমাধান রয়েছে যা কোনও ওএসের কোনও ওএস পাথের সাথে কাজ করে বলে মনে হচ্ছে।
অন্য কোনও মডিউল প্রয়োজন হয় না, এবং কোনও প্রাক-প্রসেসিংয়ের প্রয়োজন হয় না:
import re
def extract_basename(path):
"""Extracts basename of a given path. Should Work with any OS Path on any OS"""
basename = re.search(r'[^\\/]+(?=[\\/]?$)', path)
if basename:
return basename.group(0)
paths = ['a/b/c/', 'a/b/c', '\\a\\b\\c', '\\a\\b\\c\\', 'a\\b\\c',
'a/b/../../a/b/c/', 'a/b/../../a/b/c']
print([extract_basename(path) for path in paths])
# ['c', 'c', 'c', 'c', 'c', 'c', 'c']
extra_paths = ['C:\\', 'alone', '/a/space in filename', 'C:\\multi\nline']
print([extract_basename(path) for path in extra_paths])
# ['C:', 'alone', 'space in filename', 'multi\nline']
হালনাগাদ:
আপনি শুধুমাত্র একটি চান সম্ভাব্য ফাইলের নাম, যদি বর্তমান (অর্থাত, /a/b/
একটি Dir এবং তাই হয় c:\windows\
), এর Regex পরিবর্তন করুন: r'[^\\/]+(?![\\/])$'
। "রেজেক্স চ্যালেঞ্জড" এর জন্য এটি এক ধরণের স্ল্যাশকে নেতিবাচক ফরোয়ার্ড লুকেহেডে ইতিবাচক ফরোয়ার্ড লুক এহেডকে পরিবর্তিত করে , যার ফলে পথের নামগুলি স্ল্যাশের সাথে শেষ হওয়ার পরে পথের নামের শেষ উপ-ডিরেক্টরিটির পরিবর্তে কিছুই ফেরেনি। অবশ্যই কোনও গ্যারান্টি নেই যে সম্ভাব্য ফাইলের নামটি আসলে কোনও ফাইলকে বোঝায় এবং তার জন্য os.path.is_dir()
বা os.path.is_file()
নিযুক্ত করা দরকার।
এটি নিম্নলিখিত হিসাবে মিলবে:
/a/b/c/ # nothing, pathname ends with the dir 'c'
c:\windows\ # nothing, pathname ends with the dir 'windows'
c:hello.txt # matches potential filename 'hello.txt'
~it_s_me/.bashrc # matches potential filename '.bashrc'
c:\windows\system32 # matches potential filename 'system32', except
# that is obviously a dir. os.path.is_dir()
# should be used to tell us for sure
রেজেক্স এখানে পরীক্ষা করা যেতে পারে ।
কিছু গুরুত্বপূর্ণ ছাড়া কেবলমাত্র আমার সমাধানগুলিতে কিছু নতুন (অস্থায়ী ফাইল তৈরির জন্য টেম্পাইলটিকে বিবেচনা করুন: ডি)
import tempfile
abc = tempfile.NamedTemporaryFile(dir='/tmp/')
abc.name
abc.name.replace("/", " ").split()[-1]
এর মানগুলি পাওয়া এ জাতীয় abc.name
স্ট্রিং হবে: '/tmp/tmpks5oksk7'
সুতরাং আমি /
স্থানটি একটি স্থান দিয়ে প্রতিস্থাপন করতে পারি .replace("/", " ")
এবং তারপরে কল করতে পারি split()
। এটি একটি তালিকা ফিরে আসবে এবং আমি তালিকার শেষ উপাদানটি পেয়ে যাব[-1]
কোনও মডিউল আমদানি করার দরকার নেই।
আমি কখনও ডাবল-ব্যাকস্ল্যাশড পাথ দেখিনি, সেগুলি কি বিদ্যমান? পাইথন মডিউলটির অন্তর্নির্মিত বৈশিষ্ট্যটি os
তাদের জন্য ব্যর্থ। অন্যরা সকলেই কাজ করে, এছাড়াও আপনার দ্বারা প্রদত্ত সতর্কতা os.path.normpath()
:
paths = ['a/b/c/', 'a/b/c', '\\a\\b\\c', '\\a\\b\\c\\', 'a\\b\\c',
... 'a/b/../../a/b/c/', 'a/b/../../a/b/c', 'a/./b/c', 'a\b/c']
for path in paths:
os.path.basename(os.path.normpath(path))
উইন্ডোজ বিভাজক একটি ইউনিক্স ফাইলের নাম বা উইন্ডোজ পাথে থাকতে পারে। ইউনিক্স বিভাজক কেবল ইউনিক্স পথেই থাকতে পারে। ইউনিক্স বিভাজকের উপস্থিতি একটি উইন্ডোজবিহীন পথ নির্দেশ করে।
নিম্নলিখিতগুলি ওএস নির্দিষ্ট বিভাজক দ্বারা স্ট্রিপ (কাটা ট্রেলিং বিভাজক) করবে, তারপরে বিভক্ত হয়ে ডানদিকের মানটি প্রদান করবে। এটি কুরুচিপূর্ণ, তবে উপরের অনুমানের ভিত্তিতে সহজ। যদি অনুমানটি ভুল হয় তবে দয়া করে আপডেট করুন এবং আরও সঠিক অবস্থার সাথে মেলে আমি এই প্রতিক্রিয়াটি আপডেট করব।
a.rstrip("\\\\" if a.count("/") == 0 else '/').split("\\\\" if a.count("/") == 0 else '/')[-1]
কোডের উদাহরণ:
b = ['a/b/c/','a/b/c','\\a\\b\\c','\\a\\b\\c\\','a\\b\\c','a/b/../../a/b/c/','a/b/../../a/b/c']
for a in b:
print (a, a.rstrip("\\" if a.count("/") == 0 else '/').split("\\" if a.count("/") == 0 else '/')[-1])
সম্পূর্ণতার জন্য, pathlib
অজগর 3.2+ এর সমাধান এখানে :
>>> from pathlib import PureWindowsPath
>>> paths = ['a/b/c/', 'a/b/c', '\\a\\b\\c', '\\a\\b\\c\\', 'a\\b\\c',
... 'a/b/../../a/b/c/', 'a/b/../../a/b/c']
>>> [PureWindowsPath(path).name for path in paths]
['c', 'c', 'c', 'c', 'c', 'c', 'c']
এটি উইন্ডোজ এবং লিনাক্স উভয় ক্ষেত্রেই কাজ করে।
পাইথন 2 এবং 3 উভয় ক্ষেত্রে মডিউল প্যাথলিব 2 ব্যবহার করে :
import posixpath # to generate unix paths
from pathlib2 import PurePath, PureWindowsPath, PurePosixPath
def path2unix(path, nojoin=True, fromwinpath=False):
"""From a path given in any format, converts to posix path format
fromwinpath=True forces the input path to be recognized as a Windows path (useful on Unix machines to unit test Windows paths)"""
if not path:
return path
if fromwinpath:
pathparts = list(PureWindowsPath(path).parts)
else:
pathparts = list(PurePath(path).parts)
if nojoin:
return pathparts
else:
return posixpath.join(*pathparts)
ব্যবহার:
In [9]: path2unix('lala/lolo/haha.dat')
Out[9]: ['lala', 'lolo', 'haha.dat']
In [10]: path2unix(r'C:\lala/lolo/haha.dat')
Out[10]: ['C:\\', 'lala', 'lolo', 'haha.dat']
In [11]: path2unix(r'C:\lala/lolo/haha.dat') # works even with malformatted cases mixing both Windows and Linux path separators
Out[11]: ['C:\\', 'lala', 'lolo', 'haha.dat']
আপনার টেস্টকেস সহ:
In [12]: testcase = paths = ['a/b/c/', 'a/b/c', '\\a\\b\\c', '\\a\\b\\c\\', 'a\\b\\c',
...: ... 'a/b/../../a/b/c/', 'a/b/../../a/b/c']
In [14]: for t in testcase:
...: print(path2unix(t)[-1])
...:
...:
c
c
c
c
c
c
c
pathlib2
প্ল্যাটফর্মের উপর নির্ভর করে বিভিন্ন ডিকোডার সহ সমস্ত পাথকে একীভূত অভ্যন্তরীণ উপস্থাপনায় রূপান্তর করা এখানে ধারণা । ভাগ্যক্রমে, pathlib2
একটি জেনেরিক ডিকোডার অন্তর্ভুক্ত PurePath
যা কোনও পথে কাজ করা উচিত। যদি এটি কাজ না করে, আপনি উইন্ডোজ পাথ ব্যবহার করে স্বীকৃতি জোর করতে পারেন fromwinpath=True
। এটি ইনপুট স্ট্রিংকে অংশগুলিতে বিভক্ত করবে, শেষটি হল আপনি যে পাতাটি সন্ধান করছেন তা হ'ল path2unix(t)[-1]
।
যদি তর্ক nojoin=False
, পথটি আবার যুক্ত হবে, যাতে আউটপুটটি কেবল একটি ইউনিক্স ফর্ম্যাটে রূপান্তরিত ইনপুট স্ট্রিং, যা প্ল্যাটফর্মের জুড়ে সাবপাথগুলি তুলনা করতে কার্যকর হতে পারে।
os.path
কেবলntpath
অভ্যন্তরীণভাবে মডিউলটি লোড করে । এই মডিউলটি ব্যবহার'\\'
করে, লিনাক্স মেশিনেও পাথ বিভাজকগুলি পরিচালনা করা সম্ভব । লিনাক্সের জন্যposixpath
মডিউলটিos.path
কেবলমাত্র পিক্সিক শৈল বিভাজককে অনুমতি দেওয়ার জন্য পাথ অপারেশনকে সহজ করবে'/'
।