Extraiga una parte de la ruta del archivo (un directorio) en Python

163

Necesito extraer el nombre del directorio principal de una ruta determinada. Esto es lo que parece:

c:\stuff\directory_i_need\subdir\file

Estoy modificando el contenido del "archivo" con algo que use el directory_i_neednombre (no la ruta). He creado una función que me dará una lista de todos los archivos, y luego ...

for path in file_list:
   #directory_name = os.path.dirname(path)   # this is not what I need, that's why it is commented
   directories, files = path.split('\\')

   line_replace_add_directory = line_replace + directories  
   # this is what I want to add in the text, with the directory name at the end 
   # of the line.

¿Cómo puedo hacer eso?

Thalia
fuente
1
Es posible que desee consultar esta respuesta: stackoverflow.com/a/4580931/311220
Bellota
El enlace de arriba me ayudó a entender cómo arreglar lo que hice mal. Gracias.
Thalia

Respuestas:

238
import os
## first file in current dir (with full path)
file = os.path.join(os.getcwd(), os.listdir(os.getcwd())[0])
file
os.path.dirname(file) ## directory of file
os.path.dirname(os.path.dirname(file)) ## directory of directory of file
...

Y puede continuar haciendo esto tantas veces como sea necesario ...

Editar: desde os.path , puede usar os.path.split u os.path.basename:

dir = os.path.dirname(os.path.dirname(file)) ## dir of dir of file
## once you're at the directory level you want, with the desired directory as the final path node:
dirname1 = os.path.basename(dir) 
dirname2 = os.path.split(dir)[1] ## if you look at the documentation, this is exactly what os.path.basename does.
Nisan.H
fuente
Sí extrae partes de la ruta, pero no sé cómo extraer el nombre real del directorio de la ruta.
Thalia
43

En Python 3.4 puede usar el módulo pathlib :

>>> from pathlib import Path
>>> p = Path('C:\Program Files\Internet Explorer\iexplore.exe')
>>> p.name
'iexplore.exe'
>>> p.suffix
'.exe'
>>> p.root
'\\'
>>> p.parts
('C:\\', 'Program Files', 'Internet Explorer', 'iexplore.exe')
>>> p.relative_to('C:\Program Files')
WindowsPath('Internet Explorer/iexplore.exe')
>>> p.exists()
True
Noam Manos
fuente
buena demostración de la API
Nadim Farhat
Esto también se ha transferido a versiones anteriores de Python: pathlib2
phoenix del
11

Todo lo que necesitas es parentparte si lo usas pathlib.

from pathlib import Path
p = Path(r'C:\Program Files\Internet Explorer\iexplore.exe')
print(p.parent) 

Saldrá:

C:\Program Files\Internet Explorer    

En caso de que necesite todas las partes (ya cubiertas en otras respuestas) use parts:

p = Path(r'C:\Program Files\Internet Explorer\iexplore.exe')
print(p.parts) 

Entonces obtendrás una lista:

('C:\\', 'Program Files', 'Internet Explorer', 'iexplore.exe')

Ahorra tono de tiempo.

prosti
fuente
5

Primero, vea si tiene splitunc()una función disponible dentro os.path. El primer elemento devuelto debe ser lo que desea ... pero estoy en Linux y no tengo esta función cuando importo ose intento usarlo.

De lo contrario, una forma semi fea que hace el trabajo es usar:

>>> pathname = "\\C:\\mystuff\\project\\file.py"
>>> pathname
'\\C:\\mystuff\\project\\file.py'
>>> print pathname
\C:\mystuff\project\file.py
>>> "\\".join(pathname.split('\\')[:-2])
'\\C:\\mystuff'
>>> "\\".join(pathname.split('\\')[:-1])
'\\C:\\mystuff\\project'

que muestra la recuperación del directorio justo arriba del archivo y el directorio justo arriba de eso.

ely
fuente
Edité mi entrada para mostrar el uso de rsplit que hace lo que sugieres, pero aún así me da la ruta no solo el nombre del directorio.
Thalia
1
Todavía no tengo claro lo que estás preguntando. ¿Por qué no quitas todo a la izquierda de la siguiente instancia superior de \\ entonces? Imagina que quieres la ruta, luego mantén la última entrada cuando la dividas en \\. Esto debería funcionar, ¿no?
ely
Terminé dividiendo el camino y tomando la pieza que quería, no funcionó antes, pero después de leer todas estas respuestas, descubrí lo que hice mal.
Thalia
Si leer las respuestas le ayudó, considere al menos votarlas y posiblemente aceptar una de ellas. Sin embargo, me alegra que hayas visto el error.
ely
Me gusta cómo funciona esta forma semi fea. Cambio el "\\" por un simple os.sep y funciona perfectamente para recuperar solo una fracción de una ruta.
TazgerO
1

Esto es lo que hice para extraer la parte del directorio:

for path in file_list:
  directories = path.rsplit('\\')
  directories.reverse()
  line_replace_add_directory = line_replace+directories[2]

Gracias por tu ayuda.

Thalia
fuente
0
import os

directory = os.path.abspath('\\') # root directory
print(directory) # e.g. 'C:\'

directory = os.path.abspath('.') # current directory
print(directory) # e.g. 'C:\Users\User\Desktop'

parent_directory, directory_name = os.path.split(directory)
print(directory_name) # e.g. 'Desktop'
parent_parent_directory, parent_directory_name = os.path.split(parent_directory)
print(parent_directory_name) # e.g. 'User'

Esto también debería hacer el truco.

Basti Würzburg
fuente
-1

Tienes que poner la ruta completa como un parámetro para os.path.split. Ver los documentos . No funciona como una cadena dividida.

Keith
fuente
Esto no funcionará en los nombres de ruta de tipo UNC en Windows, como los documentos de Python para el estado de cosas os.path.
ely