¿Puede un archivo por lotes de Windows determinar su propio nombre de archivo?

121

¿Puede un archivo por lotes de Windows determinar su propio nombre de archivo?

Por ejemplo, si ejecuto el archivo por lotes C: \ Temp \ myScript.bat, ¿hay un comando dentro de myScript.bat que pueda determinar la cadena "myScript.bat"?

djangofan
fuente
1
%0es lo que estas buscando. Consulte [esta pregunta] [1] para obtener más información. [1]: stackoverflow.com/questions/357315/…
Jonathon Reinhart
2
Sí, eso era lo que estaba buscando. % ~ nx0 es la respuesta.
djangofan

Respuestas:

160

Si.

Utilice la %0variable especial para obtener la ruta al archivo actual.

Escriba %~n0para obtener solo el nombre del archivo sin la extensión.

Escriba %~n0%~x0para obtener el nombre del archivo y la extensión.

También es posible escribir %~nx0para obtener el nombre y la extensión del archivo.

SLaks
fuente
1
Esto es inexacto. Tanto% 0 como% ~ n0 obtienen solo la parte del nombre de archivo. La respuesta de @djangofan es correcta.
JustJeff
5
% 0 devuelve la forma en que se llamó al archivo. Si se utilizó una ruta completa,% 0 la tendrá. Si cdingresa primero al directorio y ejecuta el lote desde allí,% 0 generalmente no tendrá la información de ruta (pero podría obtenerla de% cd% en ese caso)
Gogowitsch
@gogowitsch: ¿Estás seguro? No creo que eso sea cierto.
SLaks
En Win2012, %cd%devolverá el directorio actual del proceso que llamó al archivo por lotes. Por lo tanto, si se encuentra en un indicador D:\dir1y entra Y:\foo\bar.bat, si lo bar.battiene @echo %cd%, se mostrará D:\dir1.
Predicador
48

Puede obtener el nombre del archivo, pero también puede obtener la ruta completa, dependiendo de lo que coloque entre '% ~' y '0'. Elige entre

d -- drive
p -- path
n -- file name
x -- extension
f -- full path

Por ejemplo, desde el interior de c: \ tmp \ foo.bat, %~nx0le da "foo.bat", mientras que %~dpnx0le da "c: \ tmp \ foo.bat". Tenga en cuenta que las piezas siempre se ensamblan en orden canónico, por lo que si se pone lindo y lo intenta %~xnpd0, aún obtiene "c: \ tmp \ foo.bat"

JustJeff
fuente
3
En su bloque de código, indica que fes el nombre del archivo, pero en sus ejemplos lo usa npara el nombre del archivo. Después de algunas pruebas, parece que fes la ruta completa y nes el nombre del archivo.
Drew Chapin
@druciferre, edité la respuesta de acuerdo con su comentario
robotik
"Si te pones lindo y lo intentas %~xnpd0" ... te amo.
Mark Deven
32

Usando el siguiente script, basado en la respuesta de SLaks, determiné que la respuesta correcta es:

echo The name of this file is: %~n0%~x0
echo The name of this file is: %~nx0

Y aquí está mi guión de prueba:

@echo off
echo %0
echo %~0
echo %n0
echo %x0
echo %~n0
echo %dp0
echo %~dp0
pause

Lo que encuentro interesante es que % nx0 no funcionará, dado que sabemos que el carácter '~' generalmente se usa para quitar / recortar comillas de una variable.

djangofan
fuente
9

Tenga en cuenta que 0es un caso especial de números de parámetro dentro de un archivo por lotes, donde 0significa este archivo como se indica en la línea de comando .

Entonces, si el archivo es myfile.bat, puede llamarlo de varias maneras de la siguiente manera, cada una de las cuales le dará una salida diferente del uso de %0o %~0:

myfile

myfile.bat

mydir\myfile.bat

c:\mydir\myfile.bat

"c:\mydir\myfile.bat"

Todo lo anterior son llamadas legales si lo llama desde el lugar relativo correcto al directorio en el que existe. %~0elimina las comillas del último ejemplo, mientras %0que no lo hace.

Porque todos estos dan resultados diferentes %0 y %~0es muy poco probable que sean los que realmente desea usar.

Aquí hay un archivo por lotes para ilustrar:

@echo Full path and filename: %~f0
@echo Drive: %~d0
@echo Path: %~p0
@echo Drive and path: %~dp0
@echo Filename without extension: %~n0
@echo Filename with    extension: %~nx0
@echo Extension: %~x0
@echo Filename as given on command line: %0
@echo Filename as given on command line minus quotes: %~0
@REM Build from parts
@SETLOCAL
@SET drv=%~d0
@SET pth=%~p0
@SET fpath=%~dp0
@SET fname=%~n0
@SET ext=%~x0
@echo Simply Constructed name: %fpath%%fname%%ext%
@echo Fully  Constructed name: %drv%%pth%%fname%%ext%
@ENDLOCAL
pause
Jool
fuente
3

Intente ejecutar el siguiente ejemplo para sentir cómo funcionan las variables mágicas.

@echo off

SETLOCAL EnableDelayedExpansion

echo Full path and filename: %~f0
echo Drive: %~d0
echo Path: %~p0
echo Drive and path: %~dp0
echo Filename without extension: %~n0
echo Filename with    extension: %~nx0
echo Extension: %~x0

echo date time : %~t0
echo file size: %~z0

ENDLOCAL

Se siguen las reglas relacionadas.

%~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
%~$PATH:I   - searches the directories listed in the PATH
               environment variable and expands %I to the
               fully qualified name of the first one found.
               If the environment variable name is not
               defined or the file is not found by the
               search, then this modifier expands to the
               empty string
Cary
fuente
0

A continuación se muestra mi código inicial:

@echo off
Set z=%%
echo.
echo %z%0.......%0
echo %z%~0......%~0
echo %z%n0......%n0
echo %z%x0......%x0
echo %z%~n0.....%~n0
echo %z%dp0.....%dp0
echo %z%~dp0....%~dp0
echo.

Me di cuenta de que el nombre de archivo proporcionado por% ~ 0 y% 0 es la forma en que se ingresó en el shell de comandos y no el nombre real de ese archivo. Entonces, si desea que se use el caso literal para el nombre del archivo, debe usar% ~ n0. Sin embargo, esto dejará fuera la extensión del archivo. Pero si conoce el nombre del archivo, puede agregar el siguiente código.

set b=%~0
echo %~n0%b:~8,4%

He aprendido que ": ~ 8,4%" significa comenzar en el noveno carácter de la variable y luego mostrar mostrar los siguientes 4 caracteres. El rango es 0 hasta el final de la cadena de variables. ¡Entonces% Path% sería muy largo!

fIlEnAmE.bat
012345678901

Sin embargo, esto no es tan sólido como la solución de Jool (% ~ x0) anterior.

Mi evidencia:

C:\bin>filename.bat

%0.......filename.bat
%~0......filename.bat
. . .

C:\bin>fIlEnAmE.bat

%0.......fIlEnAmE.bat
%~0......fIlEnAmE.bat
%n0......n0
%x0......x0
%~n0.....FileName
%dp0.....dp0
%~dp0....C:\bin\

%~n0%b:~8,4%...FileName.bat

Press any key to continue . . .

C:\bin>dir
 Volume in drive C has no label.
 Volume Serial Number is CE18-5BD0

 Directory of C:\bin
. . .
05/02/2018  11:22 PM               208 FileName.bat

Aquí está el código final

@echo off
Set z=%%
set b=%~0
echo.
echo %z%0.......%0
echo %z%~0......%~0
echo %z%n0......%n0
echo %z%x0......%x0
echo %z%~n0.....%~n0
echo %z%dp0.....%dp0
echo %z%~dp0....%~dp0
echo.
echo A complex solution:
echo ===================================
echo %z%~n0%z%b:~8,4%z%...%~n0%b:~8,4%
echo ===================================
echo.
echo The preferred solution:
echo ===================================
echo %z%~n0%z%~x0.......%~n0%~x0
echo ===================================
pause
Fred Tusing
fuente