¿Cuál es la mejor manera de hacer una subcadena en un archivo por lotes?


Quiero obtener el nombre del archivo por lotes actualmente en ejecución sin la extensión del archivo.

Gracias a este enlace, tengo el nombre de archivo con la extensión... pero, ¿cuál es la mejor manera de hacer una subcadena en un archivo por lotes?

¿O hay otra forma de obtener el nombre del archivo sin la extensión?

Es seguro asumir extensiones de 3 letras en este escenario.

 174
Author: Community, 2009-03-12

3 answers

Bueno, para obtener el nombre de archivo de su lote, la forma más fácil sería usar %~n0.

@echo %~n0

Mostrará el nombre (sin la extensión) del archivo por lotes actualmente en ejecución (a menos que se ejecute en una subrutina llamada por call). La lista completa de tales sustituciones "especiales" para los nombres de ruta se puede encontrar en help for, al final de la ayuda:

Además, la sustitución de POR se han mejorado las referencias de variables. Ahora puede utilizar el siguiente opcional sintaxis:

%~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

Los modificadores se pueden combinar para obtener resultados compuestos:

%~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

Para responder con precisión a su pregunta, sin embargo: Las subcadenas se hacen usando la notación :~start,length:

%var:~10,5%

Extraerá 5 caracteres de la posición 10 en la variable de entorno %var%.

NOTA: El índice de las cadenas está basado en cero, por lo que el primer carácter está en la posición 0, el segundo en 1, etc.

Para obtener subcadenas de variables de argumento como %0, %1, etc. primero tienes que asignarlos a una variable de entorno normal usando set:

:: Does not work:
@echo %1:~10,5

:: Assign argument to local variable first:
set var=%1
@echo %var:~10,5%

La sintaxis es aún más poderosa:

  • %var:~-7% extrae los últimos 7 caracteres de %var%
  • %var:~0,-4% extraería todos los caracteres excepto los últimos cuatro, lo que también eliminaría la extensión del archivo (asumiendo tres caracteres después del período [.]).

Vea help set para detalles sobre esa sintaxis.

 364
Author: Joey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-23 08:40:06

Muy bien explicado arriba!

Para todos aquellos que puedan sufrir como yo para conseguir que esto funcione en un Windows localizado (el mío es XP en eslovaco), puede tratar de reemplazar el % con un !

Así que:

SET TEXT=Hello World
SET SUBSTRING=!TEXT:~3,5!
ECHO !SUBSTRING!
 30
Author: BrandonSk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-23 08:46:18

Como información adicional a la respuesta de Joey, que no se describe en la ayuda de set /? ni for /?.

%~0 se expande al nombre del propio lote, exactamente como fue escrito.
Así que si inicia su lote se expandirá como

%~0   - mYbAtCh
%~n0  - mybatch
%~nx0 - mybatch.bat

Pero hay una excepción, expandirse en una subrutina podría fallar

echo main- %~0
call :myFunction
exit /b

:myFunction
echo func - %~0
echo func - %~n0
exit /b

Esto resulta en

main - myBatch
Func - :myFunction
func - mybatch

En una función %~0 se expande siempre al nombre de la función, no del archivo por lotes.
Pero si se utiliza en al menos un modificador mostrará el nombre del archivo de nuevo!

 12
Author: jeb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-18 06:46:42