2010-08-23 4 views
47

Esiste una funzione incorporata in Python che dovrebbe sostituire (o rimuovere, qualunque sia) l'estensione di un nome file (se ne ha uno)?Come sostituire (o rimuovere) un'estensione da un nome file in Python?

Esempio:

print replace_extension('/home/user/somefile.txt', '.jpg') 

Nel mio esempio: /home/user/somefile.txt sarebbe diventato /home/user/somefile.jpg

Non so se è importante, ma ho bisogno di questo per un modulo SCons che sto scrivendo. (Quindi forse c'è qualche funzione specifica di SCons che posso usare?)

Vorrei qualcosa pulito. Fare una semplice sostituzione di stringa di tutte le occorrenze di .txt all'interno della stringa ovviamente non è pulito. (Questo fallirebbe se il mio nome fosse somefile.txt.txt.txt)

+1

possibile duplicazione di [Estrazione dell'estensione dal nome del file in Python] (http://stackoverflow.com/questions/541390/extracting-extension-from-filename-in-python) –

+0

SCons consente di accedere alla base file in una stringa di azioni. Puoi pubblicare la tua logica specifica di scons che ha bisogno di questo? Questo è per azione, emettitore, scanner? – bdbaddog

risposta

81

Provare os.path.splitext dovrebbe fare quello che vuoi.

import os 
print os.path.splitext('/home/user/somefile.txt')[0]+'.jpg' 
+2

@ereOn: Inoltre, in futuro, prova prima SEARCH.Funziona molto meglio per rispondere a questo tipo di domande standard. –

+3

@ S.Lott: mi creda o no. Ma l'ho fatto. Lo faccio sempre. Forse con i termini sbagliati. – ereOn

+0

@ereOn: Dato che la tua domanda usa quasi lo stesso identico fraseggio, sono un po 'sorpresa che tu non l'abbia trovata. La tua domanda ha 5 parole - di fila - che corrispondono esattamente. –

19

Come @jethro detto, splitext è il modo pulito per farlo. Ma in questo caso, è abbastanza facile spezzate a cura, poiché l'estensione deve essere la parte del nome del file che viene dopo l'ultimo periodo:

filename = '/home/user/somefile.txt' 
print(filename.rsplit(".", 1)[ 0 ]) 
# '/home/user/somefile' 

Il rsplit dice Python per eseguire le spaccature stringa a partire dal destra della stringa, e il 1 dice di eseguire al massimo una divisione (in modo che ad esempio 'foo.bar.baz' ->[ 'foo.bar', 'baz' ]). Poiché rsplit restituirà sempre un array non vuoto, possiamo indicizzare in modo sicuro 0 in esso per ottenere il nome file meno l'estensione.

+0

Grazie per le spiegazioni e per la soluzione. – ereOn

+6

Si noti che l'uso di 'rsplit' genererà risultati diversi per i file che iniziano con un punto e non hanno altre estensioni (come i file nascosti su Linux, ad esempio' .bashrc'). 'os.path.splitext' restituisce un'estensione vuota per questi, ma usando' rsplit' tratterà l'intero nome del file come un'estensione. –

+1

Questo darà anche risultati imprevisti per il nome file '/ home/john.johnson/somefile' –

3

Un altro modo per utilizzare il metodo str.rpartition(sep).

Ad esempio:

filename = '/home/user/somefile.txt' 
(prefix, sep, suffix) = filename.rpartition('.') 

new_filename = prefix + '.jpg' 

print new_filename 
2

Preferisco la seguente approccio one-liner utilizzando str.rsplit():

my_filename.rsplit('.', 1)[0] + '.jpg' 

Esempio:

>>> my_filename = '/home/user/somefile.txt' 
>>> my_filename.rsplit('.', 1) 
>>> ['/home/user/somefile', 'txt'] 
+0

Questo fallisce se il file di un file non ha estensione e l'utente è 'john.doe'. –

0

Per 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' 
+0

Penso all'approccio pathlib suggerito da JS. è molto più semplice. – h0b0

13

Ampliando la risposta di Anapana, come rimuovere un interno utilizzando pathlib (Python> = 3.4):

from pathlib import Path 

filename = Path('/some/path/somefile.ext') 

filename_wo_ext = filename.with_suffix('') 

print(filename) 
print(filename_wo_ext) 

/some/path/somefile.ext
/qualche/percorso/somefile

+3

Per Python 3.x questa dovrebbe essere la risposta pathlib è il futuro ... – jlandercy