2010-03-07 32 views
12

Necesito encontrar el nombre del directorio padre para un archivo en DOSObtener el nombre del directorio padre para un archivo en particular el uso de secuencias de comandos por lotes DOS

por ej.

Supongamos que este es el directorio de

C:\test\pack\a.txt 

Tengo un script que me pide el nombre del archivo

C:\\>getname.bat  
enter file name: c:\test\pack\a.txt 

ahora la secuencia de comandos debe devolver sólo el nombre principal del archivo.

pack   

y NO la ruta principal completa al archivo.

c:\test\pack 

Respuesta

9

ver this pregunta

@echo OFF 
set mydir="%~p1" 
SET mydir=%mydir:\=;% 

for /F "tokens=* delims=;" %%i IN (%mydir%) DO call :LAST_FOLDER %%i 
goto :EOF 

:LAST_FOLDER 
if "%1"=="" (
    @echo %LAST% 
    goto :EOF 
) 

set LAST=%1 
SHIFT 

goto :LAST_FOLDER
+0

Gracias .. U r genio :) .. funciona perfectamente –

+0

no veo la forma en que se puede trabajar. % ~ p1 no funciona para mí. Solo funciona con% ~ dp0 o% ~ p0. – djangofan

+0

@djangofan El script toma una ruta como argumento y devuelve el nombre del directorio de la ruta. – asdfg

1

puede utilizar un VBScript, por ejemplo, guardar la continuación como getpath.vbs

Set objFS = CreateObject("Scripting.FileSystemObject") 
Set objArgs = WScript.Arguments 
strFile = objArgs(0) 
WScript.Echo objFS.GetParentFolderName(strFile) 

continuación, en la línea de comandos o en su lote, hacer esto

C:\test>cscript //nologo getpath.vbs c:\test\pack\a.txt 
c:\test\pack 

Si desea un método por lotes, puede mirar for /?.

%~fI  - expands %I to a fully qualified path name 
    %~dI  - expands %I to a drive letter only 
    %~pI  - expands %I to a path only 
10

La primera respuesta anterior no funciona si el nombre del directorio principal contiene un espacio. Las siguientes obras:

@echo off 
setlocal 

set ParentDir=%~p1 
set ParentDir=%ParentDir: =:% 
set ParentDir=%ParentDir:\= % 
call :getparentdir %ParentDir% 
set ParentDir=%ParentDir::= % 

echo ParentDir is %ParentDir% 
goto :EOF 

:getparentdir 
if "%~1" EQU "" goto :EOF 
Set ParentDir=%~1 
shift 
goto :getparentdir 

llamando a la anterior con el parámetro de "C: \ Temp \ Parent Dir Con Espacio \ miarchivo.txt" da siguiente:

>GetParentDir "C:\Temp\Parent Dir With Space\myfile.txt" 
ParentDir is Parent Dir With Space 

los trabajos anteriores mediante la sustitución de los espacios con dos puntos (Esto no debería existir en las rutas de Windows), luego reemplaza los delimitadores de directorios con espacios para que los directorios individuales se pasen a getparentdir como argumentos separados. Funcione getparentdir loops hasta que encuentre su último argumento. Finalmente, todos los dos puntos en el resultado se reemplazan por espacios.

+0

¿es posible hacerlo funcionar para nombres de archivos que incluyen comas? caso especial, lo sé, solo me pregunto si sería una simple adición o una gran cantidad de código adicional. gracias – GeorgeCostanza

1

Aquí hay una manera que no usa CALL y creo que es más rápido.Based on jeb's splitting function (podría fallar si el nombre del directorio contiene !):

@echo off 

set "mydir=%~p1" 
SET mydir=%mydir:~0,-1% 

setlocal EnableDelayedExpansion 
set LF=^ 


rem ** Two empty lines are required 

for %%L in ("!LF!") DO (
    set "dir_name=!mydir:\=%%L!" 
) 
for /f "delims=" %%P in (""!dir_name!"") do set "dn=%%~P" 
echo %dn% 

exit /b 0 
+0

esto funciona muy bien. ¿Hay alguna manera simple de agregar casos especiales para los signos de exclamación, etc. o las secuencias de comandos de DOS son demasiado limitadas? – GeorgeCostanza

0

Aquí hay otra solución:

SET LAST=%CD% 
SET PARENTNAME=NONE 
cd /D C:\test\pack 
FOR %%I in (%CD%) do SET PARENTNAME=%%~nI 
cd /D %LAST% 
ECHO %PARENTNAME% 

%% ~ nI: '~ n' extrae el nombre de la ruta almacenada en %% variable I
cd: parámetro '/ D' añadió para cambiar entre los discos también

1

me encontré con esta combinación de enfoques de las respuestas de djangofan y paranoico a ser a la vez, sencillo y perfectamente s ufficient, al mirar para arriba directorio padre de mi guión:

set FULL_PATH=%~dp0 
set FULL_PATH=%FULL_PATH:~1,-1% 
for %%i in ("%FULL_PATH%") do set "PARENT_FOLDER=%%~ni" 
echo %PARENT_FOLDER% 

Puesto que usted quiere trabajar en la entrada del usuario en su lugar, usted tiene que hacer un trabajo adicional mínimo, para manejar las variaciones legales como C: \ foo \ bar \ a. txt vs. C: \ foo \ bar \ a.txt o c: /foo/bar/a.txt. Esto podría luego trabajar para usted:

@setlocal 
@echo off 

call:GET_PARENT_FOLDER C:\foo\bar\a.txt 
echo %PARENT_FOLDER% 
call:GET_PARENT_FOLDER C:\foo\bar\\a.txt 
echo %PARENT_FOLDER% 
call:GET_PARENT_FOLDER c:/foo/bar/a.txt 
echo %PARENT_FOLDER% 

pause 
goto:EOF 

:GET_PARENT_FOLDER 
:: Strip the filename, so we get something like this: 'C:\foor\bar\' 
set "_FULL_PATH=%~dp1" 

:: Strips all dangling '\' and '/' in a loop, so the last folder name becomes accessible 
:_STRIP 
if not "%_FULL_PATH:~-1%"=="\" if not "%_FULL_PATH:~-1%"=="/" goto:_STRIP_END 
set "_FULL_PATH=%_FULL_PATH:~1,-1%" 
goto:_STRIP 
:_STRIP_END 

:: We need the context of a for-loop for the special path operators to be available 
for %%i in ("%_FULL_PATH%") do set "PARENT_FOLDER=%%~ni" 

goto:EOF 
7

Puede ser muy simple para obtener la carpeta principal del archivo por lotes:

@echo off 
for %%a in ("%~dp0\.") do set "parent=%%~nxa" 
echo %parent% 

Y para un padre de una ruta de archivo de acuerdo con la pregunta:

@echo off 
for %%a in ("c:\test\pack\a.txt") do for %%b in ("%%~dpa\.") do set "parent=%%~nxb" 
echo %parent% 
+0

Encontré esto útil para encontrar una carpeta principal que fuera un par de directorios encima del archivo por lotes. Simplemente agregue '\ ..' después del '% ~ dp0 \ .' para subir un nivel de carpeta. Ejemplo: 'para %% a in ("% ~ dp0 \. \ .. \ .. \ .. ") establece" parent = %% ~ nxa "' – Toomaja

1

La idea de DaDummy funcionó en funciones reutilizables más prácticas. También el primer carácter de _full_path ahora está incluido.

set map=D:\test1\test2\test3\test4.txt 
call:get_parent_path "%map%" 
echo full_path is %_full_path% 
call:get_parent_path %_full_path% 
echo full_path is %_full_path% 
call:get_last_path %_full_path% 
echo last_path is %_last_path% 
goto :eof 

:get_parent_path 
set "_full_path=%~dp1" 
:_strip 
if not "%_full_path:~-1%"=="\" if not "%_full_path:~-1%"=="/" goto:_strip_end 
set "_full_path=%_full_path:~0,-1%" 
goto:_strip 
:_strip_end 
exit /b 

:get_last_path 
set "_last_path=%~nx1" 
exit /b 

::result: 
::full_path is D:\test1\test2\test3 
::full_path is D:\test1\test2 
::last_path is test2 
Cuestiones relacionadas