답변:
사용 os.path.split
또는 os.path.basename
다른 사람이 모든 경우에하지 않습니다 작업을 제안 같이 리눅스에서 스크립트를 실행하고 고전적인 윈도우 스타일의 경로를 처리하려고 시도하는 경우, 실패합니다.
Windows 경로는 백 슬래시 또는 슬래시를 경로 구분 기호로 사용할 수 있습니다. 따라서 ntpath
모듈 (Windows에서 실행할 때 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) 한 가지주의 사항이 있습니다. Linux 파일 이름 에는 백 슬래시가 포함될 수 있습니다 . 따라서 Linux에서는 r'a/b\c'
항상 폴더 의 파일 b\c
을 참조하고 a
Windows에서는 항상c
b
폴더의 하위 폴더에있는 파일을a
합니다. 앞뒤 슬래시가 경로에 사용하는 경우 그래서, 당신은 필요 올바르게 해석 할 수 있도록 관련 플랫폼을 알고. 실제로 Linux 파일 이름에는 백 슬래시가 거의 사용되지 않으므로 일반적으로 Windows 경로라고 가정하는 것이 안전하지만 코드를 작성할 때이 점을 명심하여 실수로 보안 허점을 만들지 마십시오.
r'C:\path\to\file.txt'
Linux 시스템에서 Windows 스타일 경로 (예 :) 를 구문 분석해야하는 경우에만 ntpath 모듈을 사용해야합니다. 그렇지 않으면 os.path의 기능을 사용할 수 있습니다. Linux 시스템은 일반적으로 파일 이름에 백 슬래시 문자를 사용할 수 있기 때문입니다 (답변에 설명 된대로).
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')
tail은 원하는 파일 이름입니다.
자세한 내용은 Python OS 모듈 문서 를 참조하십시오
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
정답을 제공 했다고 생각 합니다. 내 코드는 유닉스 시스템의 Windows와 같은 경로와 Windows 시스템의 유닉스와 같은 경로에서 작동하지 않습니다.
r"a\b\c"
Linux 또는 "a/b/c"
Windows 에서는 작동하지 않습니다 .
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]
이것은 반환됩니다 : paint.exe
경로 또는 OS와 관련하여 split 함수의 sep 값을 변경하십시오.
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]))
그러나 일반적으로 Windows 경로에서 찾을 수있는 "\"로 경로가 분산되면 다음 코드를 사용할 수 있습니다
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]))
OS 유형을 확인하여 하나의 함수로 결합하여 결과를 반환 할 수 있습니다.
이것은 표준 라이브러리와 함께 Linux 및 Windows에서 작동합니다.
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']
다음은 정규식 전용 솔루션이며 모든 OS의 모든 OS 경로에서 작동하는 것 같습니다.
다른 모듈이 필요하지 않으며 사전 처리가 필요하지 않습니다.
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\
) 정규식을 다음으로 변경하십시오 r'[^\\/]+(?![\\/])$'
. "regex challengeed"의 경우, 이것은 슬래시 에 대한 포지티브 포워드 룩어 헤드를 네거티브 포워드 룩어 헤드로 변경하여, 슬래시 로 끝나는 경로명이 경로명 의 마지막 하위 디렉토리 대신 아무것도 반환하지 않도록합니다. 물론 잠재적 인 파일 이름이 실제로 파일을 나타내 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
정규식은 여기에서 테스트 할 수 있습니다 .
어쩌면 중요하지 않은 하나의 솔루션으로 내 모든 것을 어쩌면 (임시 파일을 만드는 임시 파일 : D)
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))
Windows 구분 기호는 Unix 파일 이름 또는 Windows 경로에있을 수 있습니다. Unix 구분 기호는 Unix 경로에만 존재할 수 있습니다. Unix 구분 기호가 있으면 Windows가 아닌 경로를 나타냅니다.
다음은 OS 특정 구분 기호로 잘라 내기 구분 기호를 제거한 다음 가장 오른쪽 값을 나누고 반환합니다. 추악하지만 위의 가정에 따라 간단합니다. 가정이 올바르지 않은 경우 업데이트하십시오.보다 정확한 조건에 맞게이 응답을 업데이트하겠습니다.
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
Python 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']
이것은 Windows와 Linux 모두에서 작동합니다.
Python 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
있습니다. 이것이 작동하지 않는 경우을 사용하여 Windows 경로를 강제로 인식 할 수 있습니다 fromwinpath=True
. 이것은 입력 문자열을 여러 부분으로 나눕니다. 마지막은 찾고있는 잎 path2unix(t)[-1]
입니다.
인수 nojoin=False
인 경우 경로가 다시 결합되므로 출력은 단순히 Unix 형식으로 변환 된 입력 문자열이므로 플랫폼 간 하위 경로를 비교하는 데 유용 할 수 있습니다.
os.path
로드합니다ntpath
. 이 모듈을 사용하면'\\'
Linux 시스템에서도 경로 구분 기호 를 처리 할 수 있습니다 . Linux의 경우posixpath
모듈 (resp.os.path
)은 posix 스타일'/'
구분 기호 만 허용하도록 경로 조작을 단순화합니다 .