Cómo obtener la ruta de la carpeta desde la ruta del archivo con CMD

151

Necesito ruta a la carpeta que contiene el archivo cmd. Con% 0 puedo obtener el nombre del archivo. ¿Pero cómo obtener el nombre de la carpeta?

c: \ temp \ test.cmd >> test.cmd

PD: Mi directorio actual! = Carpeta de la secuencia de comandos.

Mike Chaliy
fuente

Respuestas:

310

Para el nombre de la carpeta y la unidad, puede usar:

echo %~dp0

Puede obtener mucha más información utilizando diferentes modificadores:

%~I         - expands %I removing any surrounding quotes (")
%~fI        - expands %I to a fully qualified path name
%~dI        - expands %I to a drive letter only
%~pI        - expands %I to a path only
%~nI        - expands %I to a file name only
%~xI        - expands %I to a file extension only
%~sI        - expanded path contains short names only
%~aI        - expands %I to file attributes of file
%~tI        - expands %I to date/time of file
%~zI        - expands %I to size of file

The modifiers can be combined to get compound results:
%~dpI       - expands %I to a drive letter and path only
%~nxI       - expands %I to a file name and extension only
%~fsI       - expands %I to a full path name with short names only

Esta es una copia pegada de "for /?" comando en el indicador. Espero eso ayude.

Relacionado

Los 10 consejos principales de DOS Batch (Sí, DOS Batch ...) muestran batchparams.bat (enlace a la fuente como una idea general):

C:\Temp>batchparams.bat c:\windows\notepad.exe
%~1     =      c:\windows\notepad.exe
%~f1     =      c:\WINDOWS\NOTEPAD.EXE
%~d1     =      c:
%~p1     =      \WINDOWS\
%~n1     =      NOTEPAD
%~x1     =      .EXE
%~s1     =      c:\WINDOWS\NOTEPAD.EXE
%~a1     =      --a------
%~t1     =      08/25/2005 01:50 AM
%~z1     =      17920
%~$PATHATH:1     =
%~dp1     =      c:\WINDOWS\
%~nx1     =      NOTEPAD.EXE
%~dp$PATH:1     =      c:\WINDOWS\
%~ftza1     =      --a------ 08/25/2005 01:50 AM 17920 c:\WINDOWS\NOTEPAD.EXE
Wadih M.
fuente
Frio. ¿Necesito un puntaje particular para modificar la publicación wiki de otra persona?
Wadih M.
@Wadih M .: enlace generalmente útil stackoverflow.com/questions/18557/…
jfs
@Wadih M .: En particular stackoverflow.com/questions/130654/…
jfs
@Wadih M .: desde el enlace anterior: "+750 para editar publicaciones de la comunidad 'wiki editable'"
jfs
Entonces, si desea que un script cmd establezca el directorio de trabajo en la ubicación del script: cd /d "%~dp0"(de stackoverflow.com/questions/4451668 )
Nigel Touch
52

La respuesta aceptada es útil, pero no es inmediatamente obvio cómo recuperar un nombre de archivo de una ruta si NO está utilizando valores pasados. Pude resolver esto desde este hilo, pero en caso de que otros no tengan tanta suerte, así es como se hace:

@echo off
setlocal enabledelayedexpansion enableextensions

set myPath=C:\Somewhere\Somewhere\SomeFile.txt
call :file_name_from_path result !myPath!
echo %result%
goto :eof

:file_name_from_path <resultVar> <pathVar>
(
    set "%~1=%~nx2"
    exit /b
)

:eof
endlocal

Ahora la :file_name_from_pathfunción se puede usar en cualquier lugar para recuperar el valor, no solo para pasar en argumentos. Esto puede ser extremadamente útil si los argumentos se pueden pasar al archivo en un orden indeterminado o si la ruta no se pasa al archivo en absoluto.

NightOwl888
fuente
¡Guau eso es increible! Entonces, los archivos por lotes de Windows admiten la función dentro del mismo archivo, ¡qué útil! ¿Desde cuándo fue esto posible?
Lucas
2
Me gusta que pueda pasar variables tanto por referencia (como es) como por valor (rodeado de "!" S). Ok, probablemente no tenga variables "locales" y una pila de llamadas ... pero bueno, después de todo es un script cmd, de todos modos es un gran paso adelante;) Estoy de acuerdo, particionar cosas dentro de un solo archivo es mucho más útil que dividirlo en varios archivos :)
Luke
1
Creo que "goto: eof" debería ser "goto eof" ... sin el colon ... ya que se estaba rompiendo para mí.
Un Khudairy
2
Consulte también: ss64.com/nt/syntax-args.html : use solo %~dp1para unidad y ruta.
Andrew
2
@AKhudairy es correcto: ss64.com/nt/goto.html Con el colon, el goto omite el endlocal (y cualquier otra cosa que coloque después, como una pausa). También debe agregar "s alrededor !myPath!si su ruta tiene espacios (o hacer que las comillas formen parte de myPath)
Rick
8

Para asignarlos a las variables, asegúrese de no agregar espacios al frente o después del signo igual:

set filepath=%~dp1
set filename=%~nx1

Entonces no deberías tener problemas.

Franco
fuente
5

En caso de que alguien quiera un método alternativo ...

Si es el último subdirectorio en la ruta, puede usar este one-liner:

cd "c:\directory\subdirectory\filename.exe\..\.." && dir /ad /b /s

Esto devolvería lo siguiente:

c:\directory\subdirectory

El .... regresa al directorio anterior. / ad muestra solo directorios / b es una lista de formato simple que incluye todos los subdirectorios. Esto se utiliza para obtener la ruta completa del directorio para imprimir.

marca
fuente
Probablemente funciona contra el directorio actual, no un directorio donde se encuentra el archivo de script.
Mike Chaliy
4

Tuve el mismo problema en mi bucle donde quería extraer archivos zip en el mismo directorio y luego eliminar el archivo zip. El problema era que 7z requiere la carpeta de salida, así que tuve que obtener la ruta de la carpeta de cada archivo. Aquí está mi solución:

FOR /F "usebackq tokens=1" %%i IN (`DIR /S/B *.zip` ) DO (
  7z.exe x %%i -aoa -o%%i\..
) 

%% i era una ruta completa de nombre de archivo y% ii \ .. simplemente devuelve la carpeta principal.

Espero eso ayude.

Gico
fuente
Rápido y sucio. ¡Me gusta eso! Nunca pensé que podría extender una ruta de archivo con "\ .." y terminar con la carpeta principal.
Oliver R.
Esto funcionó para mí en Win10: FOR / R "C: \ sourceDir"% I IN (* .gz) DO C: \ 7-Zip64 \ 7z.exe x "% I" -aou -o% I \ .. \
b3wii
¡Si! Esto evita el problema de que% ~ dp1 (etc.) solo funciona en% 0,% 1,% 2, etc.
Artelius
3

En caso de que la respuesta aceptada por Wadih no funcione para usted, intente echo %CD%

Naguib Ihab
fuente
0

Esto se puso junto con un ejemplo editado cmd

@Echo off

Echo ********************************************************
Echo *  ZIP Folder Backup using 7Zip                        *
Echo *  Usage: Source Folder, Destination Drive Letter      *
Echo *  Source Folder will be Zipped to Destination\Backups *
Echo ********************************************************
Echo off

set year=%date:~-4,4%
set month=%date:~-10,2%
set day=%date:~-7,2%
set hour=%time:~-11,2%
set hour=%hour: =0%
set min=%time:~-8,2%

SET /P src=Source Folder to Backup: 
SET source=%src%\*
call :file_name_from_path nam %src%
SET /P destination=Backup Drive Letter:
set zipfilename=%nam%.%year%.%month%.%day%.%hour%%min%.zip
set dest="%destination%:\Backups\%zipfilename%"


set AppExePath="%ProgramFiles(x86)%\7-Zip\7z.exe"
if not exist %AppExePath% set AppExePath="%ProgramFiles%\7-Zip\7z.exe"

if not exist %AppExePath% goto notInstalled

echo Backing up %source% to %dest%

%AppExePath% a -r -tzip %dest% %source%

echo %source% backed up to %dest% is complete!

TIMEOUT 5

exit;

:file_name_from_path <resultVar> <pathVar>
(
    set "%~1=%~nx2"
    exit /b
)


:notInstalled

echo Can not find 7-Zip, please install it from:
echo  http://7-zip.org/

:end
PAUSE
Steve Seymour
fuente