Lote: eliminar la extensión de archivo

155

Tengo el siguiente script por lotes de Wikipedia:

@echo off
    for /R "C:\Users\Admin\Ordner" %%f in (*.flv) do (
    echo %%f
)
pause

En el bucle for, todos los archivos con la extensión flv se repiten, pero quiero realizar algunas acciones con los archivos donde necesito una vez el archivo sin la extensión y una vez con la extensión. ¿Cómo podría obtener estos dos?

Busqué soluciones pero no encuentro ninguna. Soy un verdadero novato en lote ...

Poru
fuente

Respuestas:

309

Puede usar %%~nfpara obtener el nombre de archivo solo como se describe en la referencia para for:

@echo off
    for /R "C:\Users\Admin\Ordner" %%f in (*.flv) do (
    echo %%~nf
)
pause

Las siguientes opciones están disponibles:

Variable con modificador Descripción

% ~ I ​​Expande% I, lo que elimina cualquier entorno 
                        comillas ("").
% ~ fI Expande% I a un nombre de ruta completamente calificado.
% ~ dI Expande% I a una letra de unidad solamente.
% ~ pI Expande% I solo a una ruta.
% ~ nI Expande% I solo a un nombre de archivo.
% ~ xI Expande% I a una extensión de archivo solamente.
% ~ sI Expande la ruta para contener solo nombres cortos.
% ~ aI Expande% I a los atributos del archivo.
% ~ tI Expande% I a la fecha y hora del archivo.
% ~ zI Expande% I al tamaño del archivo.
% ~ $ PATH: I Busca en los directorios listados en el entorno PATH 
                        variable y expande% I al nombre completo de 
                        El primero encontrado. Si el nombre de la variable de entorno es
                        no definido o la búsqueda no encuentra el archivo,
                        Este modificador se expande a la cadena vacía.    
Dirk Vollmar
fuente
8
Solo una nota rápida: en el ejemplo anterior, %% f sería algo así C:\Users\Admin\Ordner\foo.flvcomo %% ~ nf le daría foo. Si desea todo excepto la extensión, use %% ~ df %% ~ pf %% ~ nf que le daríaC:\Users\Admin\Ordner\foo
ehambright
8
@ehambright Comentario tardío, pero supongo que usar %%~dpnfsería una alternativa más corta.
Gracias por el modificador / tabla descriptiva Dirk. Mi caso fue obtener el nombre del archivo sin extensión de param %1en un script por lotes. echo %~n1era lo que buscaba.
Dave Pile
26

En caso de que el archivo que contiene su variable no exista, el FORenfoque no funcionará. Un truco que podría usar, si conoce la longitud de la extensión, es tomar una subcadena:

%var:~0,-4%

los -4medios que los últimos 4 dígitos (presumiblemente .ext se truncarán).

Ohad Schneider
fuente
Esto no funciona para mí (en Win8.1), tal vez lo malinterpreto cuando lo intento echo %f:~0,-4%en el contexto del ejemplo utilizado en la pregunta. ¿Qué estoy haciendo mal?
Lobo
2
Aparentemente, eso funciona para variables "normales", no para variables FOR (o tal vez simplemente no conozco la sintaxis correcta). De todos modos, esto funcionará en el contexto del ejemplo de OP: SET fl=%%fy luegoecho %fl:~0,-4%
Ohad Schneider
@Wolf, debe establecer el valor de la variable de bucle en una variable normal y luego hacer la sustitución / truncamiento de la cadena en la variable normal
phuclv
En casos más que suficientes, la longitud de extensión no es igual a 3 o es desconocida. Todavía puede usar un incluso si el archivo no existe, vea mi respuesta.
marsze
14

También soy un desconocido para cmd de windows, pero intente esto:

echo %%~nf
Vineet
fuente
8

Esta es una respuesta realmente tardía, pero se me ocurrió esto para resolver un problema particular que tuve con DiskInternals LinuxReader agregando '.efs_ntfs' a los archivos que guardó en directorios que no son NTFS (FAT32):

@echo off
REM %1 is the directory to recurse through and %2 is the file extension to remove
for /R "%1" %%f in (*.%2) do (
    REM Path (sans drive) is given by %%~pf ; drive is given by %%~df
    REM file name (sans ext) is given by %%~nf ; to 'rename' files, move them
    copy "%%~df%%~pf%%~nf.%2" "%%~df%%~pf%%~nf"
    echo "%%~df%%~pf%%~nf.%2" copied to "%%~df%%~pf%%~nf"
echo.
)
pause
Agi Hammerthief
fuente
No estoy seguro de que responda la pregunta, pero en realidad me ayudó, ¡gracias!
matan7890
1
@ matan7890 Verdadero; la operación no especifica qué implica "Quiero que se realicen algunas acciones con los archivos" [sic], pero una de esas acciones puede ser renombrarlas, en cuyo caso mi respuesta es una expansión de la respuesta aceptada.
Agi Hammerthief
Esto ayudó a un amigo mío que abrió un archivo adjunto y lo .encryptedagregó a todos sus archivos, junto con una demanda de rescate. Aparentemente, el script de ataque debe haber sido un archivo por lotes que es el reverso de esto y agregado .encrypteda todos los archivos.
AwokeKnowing
1
votó porque menciona la unidad, la ruta y la extensión ( %% ~ df %% ~ pf %% ~ nf ) que se parece más a la salida de %% f de la pregunta original, en lugar de solo el nombre de archivo sin extensión ( %% ~ nf )
ehambright
5

Estoy usando esto si simplemente quiero quitar la extensión de una variable (sin repetir ningún directorio o archivo existente):

for %%f in ("%filename%") do set filename=%%~nf

Si desea quitar la extensión de una ruta completa, use %%dpnfen su lugar:

for %%f in ("%path%") do set path=%%~dpnf

Ejemplo:

(Usar directamente en la consola)

@for %f in ("file name.dat") do @echo %~nf
@for %f in ("C:\Dir\file.dat") do @echo %~dpnf

OUTPUT:

file name
C:\Dir\file
marsze
fuente
0

Usando cygwin bash para cortar

  :: e.g. FILE=basename.mp4 => FILE_NO_EXT=basename
  set FILE=%1
  for /f "delims=" %%a in ('bash -c "FILE=%FILE%; echo ${FILE/.*/}" ') do set FILE_NO_EXT=%%a
mosh
fuente
0

Si su variable es un argumento, simplemente puede usar %~dpnseguido del número del argumento, para que no tenga que preocuparse por las diferentes longitudes de extensión.

Por ejemplo %~dpn0, devolverá la ruta del archivo por lotes sin su extensión, %~dpn1será %1sin extensión, etc.

Martin Braun
fuente