जवाबों:
अन्य मामलों में उपयोग os.path.splitया os.path.basenameसुझाव देने से काम नहीं चलेगा: यदि आप लिनक्स पर स्क्रिप्ट चला रहे हैं और क्लासिक विंडो-स्टाइल पथ को संसाधित करने का प्रयास कर रहे हैं, तो यह विफल हो जाएगा।
Windows पथ पथ विभाजक के रूप में बैकस्लैश या फ़ॉरवर्ड स्लैश का उपयोग कर सकते हैं। इसलिए, ntpathमॉड्यूल (जो विंडोज़ पर चलने के दौरान ओएस के बराबर है । ) सभी प्लेटफार्मों पर सभी (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, जबकि विंडोज पर, यह हमेशा फ़ोल्डर cके bसबफ़ोल्डर में फ़ाइल को संदर्भित करता है 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
अजगर में ३
>>> from pathlib import Path
>>> Path("/tmp/d/a.dat").name
'a.dat'
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]
यह वापस आएगा: पेंट। exe
अपने पथ या OS के बारे में विभाजन फ़ंक्शन के सेप मूल्य को बदलें।
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/एक निर्देशिका है और इसलिए है c:\windows\), करने के लिए regex बदलने के लिए: r'[^\\/]+(?![\\/])$'। "Regex को चुनौती दी," इस बात के लिए सकारात्मक आगे अग्रदर्शी बदलता है स्लेश किसी प्रकार का एक नकारात्मक करने के लिए तत्पर अग्रदर्शी, pathnames के कारण ही कहा साथ अंत स्लेश वापसी कुछ नहीं के बजाय पथ में पिछले उप-निर्देशिका के लिए। बेशक, इस बात की कोई गारंटी नहीं है कि संभावित फ़ाइलनाम वास्तव में एक फ़ाइल को संदर्भित करता है और इसके लिए 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 दोनों में, मॉड्यूल pathlib2 का उपयोग करते हुए :
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) केवल पॉज़िक्स स्टाइल'/'सेपरेटर की अनुमति देने के लिए पथ संचालन को सरल करेगा ।