Как заменить (или удалить) расширение из имени файла в Python?
Есть ли встроенная функция в Python, которая заменит (или удалит) расширение файла (если оно есть)?
Пример:
print replace_extension('/home/user/somefile.txt', '.jpg')
В моем примере: /home/user/somefile.txt
станет /home/user/somefile.jpg
Я не знаю, имеет ли это значение, но мне нужно это для модуля SCons, который я пишу. (Так, возможно, есть какая-то особая функция SCons, которую я могу использовать?)
Я хотел бы что-нибудь чистое. Делая простую замену строки всех вхождений .txt
внутри строки явно не чисто. (Это не удастся, если мое имя файла somefile.txt.txt.txt
)
8 ответов
Попробуйте os.path.splitext, он должен делать то, что вы хотите.
import os
print os.path.splitext('/home/user/somefile.txt')[0]+'.jpg'
Разбираясь в ответе AnaPana, как удалить расширение с помощью pathlib (Python> = 3.4):
>>> from pathlib import Path
>>> filename = Path('/some/path/somefile.txt')
>>> filename_wo_ext = filename.with_suffix('')
>>> filename_replace_ext = filename.with_suffix('.jpg')
>>> print(filename)
/some/path/somefile.ext
>>> print(filename_wo_ext)
/some/path/somefile
>>> print(filename_replace_ext)
/some/path/somefile.jpg
Как сказал @jethro, splitext
это аккуратный способ сделать это. Но в этом случае его довольно легко разбить самостоятельно, поскольку расширение должно быть частью имени файла, следующего за последним периодом:
filename = '/home/user/somefile.txt'
print( filename.rsplit( ".", 1 )[ 0 ] )
# '/home/user/somefile'
rsplit
говорит Python выполнить разбиение строки, начиная с правой части строки, и 1
говорит выполнить не более одного сплита (так что, например, 'foo.bar.baz'
-> [ 'foo.bar', 'baz' ]
). поскольку rsplit
всегда будет возвращать непустой массив, мы можем безопасно индексировать 0
в него, чтобы получить имя файла минус расширение.
Я предпочитаю следующий однострочный подход с использованием str.rsplit ():
my_filename.rsplit('.', 1)[0] + '.jpg'
Пример:
>>> my_filename = '/home/user/somefile.txt'
>>> my_filename.rsplit('.', 1)
>>> ['/home/user/somefile', 'txt']
Обработка нескольких расширений
В случае, если у вас есть несколько расширений, это однострочное использование pathlib
а также str.replace
работает угощение:
Удалить / удалить расширения
>>> from pathlib import Path
>>> p = Path("/path/to/myfile.tar.gz")
>>> str(p).replace("".join(p.suffixes), "")
'/path/to/myfile'
Заменить расширения
>>> p = Path("/path/to/myfile.tar.gz")
>>> new_ext = ".jpg"
>>> str(p).replace("".join(p.suffixes), new_ext)
'/path/to/myfile.jpg'
Если вы также хотите pathlib
вывод объекта, то вы можете, очевидно, обернуть строку в Path()
>>> Path(str(p).replace("".join(p.suffixes), ""))
PosixPath('/path/to/myfile')
Я удивлен, что никто не упомянул о pathlib
with_name
. Это решение работает с несколькими расширениями (т. Е. Заменяет все расширения).
import pathlib
p = pathlib.Path('/some/path/somefile.txt')
p = p.with_name(p.stem).with_suffix('.jpg')
Еще один способ сделать это использовать str.rpartition(sep)
метод.
Например:
filename = '/home/user/somefile.txt'
(prefix, sep, suffix) = filename.rpartition('.')
new_filename = prefix + '.jpg'
print new_filename
Для Python >= 3.4:
from pathlib import Path
filename = '/home/user/somefile.txt'
p = Path(filename)
new_filename = p.parent.joinpath(p.stem + '.jpg') # PosixPath('/home/user/somefile.jpg')
new_filename_str = str(new_filename) # '/home/user/somefile.jpg'