Lote: remover extensão de arquivo

155

Eu tenho o seguinte script em lote da Wikipedia:

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

No loop for, todos os arquivos com a extensão flv são ecoados, mas quero fazer algumas ações com o (s) arquivo (s) em que preciso uma vez o arquivo sem a extensão e outra vez com a extensão. Como eu consegui esses dois?

Procurei soluções, mas não encontrei nenhuma. Eu sou um novato de verdade em lote ...

Poru
fonte

Respostas:

309

Você pode usar %%~nfpara obter o nome do arquivo apenas conforme descrito na referência para for:

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

As seguintes opções estão disponíveis:

Variável com modificador Descrição

% ~ I ​​Expande% I, que remove qualquer ambiente 
                        aspas ("").
% ~ fI Expande% I para um nome de caminho completo.
% ~ dI Expande% I apenas para uma letra de unidade.
% ~ pI Expande% I apenas para um caminho.
% ~ nI Expande% I apenas para um nome de arquivo.
% ~ xI Expande% I apenas para uma extensão de arquivo.
% ~ sI Expande o caminho para conter apenas nomes abreviados.
% ~ aI Expande% I para os atributos de arquivo.
% ~ tI Expande% I para a data e hora do arquivo.
% ~ zI Expande% I para o tamanho do arquivo.
% ~ $ PATH: I Procura nos diretórios listados no ambiente PATH 
                        variável e expande% I para o nome completo de 
                        o primeiro encontrado. Se o nome da variável de ambiente for
                        não definido ou o arquivo não foi encontrado pela pesquisa,
                        esse modificador se expande para a cadeia vazia.    
Dirk Vollmar
fonte
8
Apenas uma observação rápida: no exemplo acima, %% f seria algo como C:\Users\Admin\Ordner\foo.flve %% ~ nf lhe daria foo. Se você quer tudo , exceto o uso de extensão %% ~ df %% ~ pf %% ~ nf que lhe dariaC:\Users\Admin\Ordner\foo
ehambright
8
@ehambright Comentário tardio, mas acho que usar %%~dpnfseria uma alternativa mais curta.
Obrigado pela tabela modificador / descrição Dirk. Meu caso foi obter o nome do arquivo sem extensão do param %1em um script em lote. echo %~n1foi o que eu estava procurando.
Dave Pilha
26

Caso o arquivo que sua variável retenha não exista, a FORabordagem não funcionará. Um truque que você pode usar, se souber o comprimento da extensão, é usar uma substring:

%var:~0,-4%

os -4meios que os últimos 4 dígitos (presumivelmente .ext ) será truncado.

Ohad Schneider
fonte
Isso não está funcionando para mim (no Win8.1) - talvez eu entenda errado ao tentar echo %f:~0,-4%no contexto do exemplo usado na pergunta. O que estou fazendo de errado?
Wolf
2
Aparentemente, isso funciona para variáveis ​​"normais", não para variáveis ​​(ou talvez eu simplesmente não conheça a sintaxe correta). De qualquer forma isso vai funcionar no contexto do exemplo OP: SET fl=%%fe depoisecho %fl:~0,-4%
Ohad Schneider
@Wolf você precisa valor definido da variável loop para uma variável normal, em seguida, fazer seqüência de substituição / truncamento na variável normal
phuclv
Em casos mais do que suficientes, o comprimento da extensão não é igual a 3 ou é desconhecido. Você ainda pode usar um para mesmo que o arquivo não exista, veja minha resposta.
marsze 17/02
14

Eu também sou um estranho para o Windows cmd, mas tente o seguinte:

echo %%~nf
Vineet
fonte
8

Essa é uma resposta realmente tardia, mas eu vim com isso para resolver um problema específico que tive com o DiskInternals LinuxReader anexando '.efs_ntfs' aos arquivos que foram salvos em diretórios não 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
fonte
Não sei se responde à pergunta, mas na verdade me ajudou, obrigado!
matan7890
1
@ matan7890 True; o op não especifica o que "Eu quero fazer algumas ações com o (s) arquivo (s)" [sic] implica, mas uma dessas ações pode ser renomeá-las, caso em que minha resposta é uma expansão da resposta aceita.
Agi Hammerthief
Isso ajudou um amigo meu que abriu um anexo e .encryptedadicionou todos os seus arquivos, juntamente com uma demanda de resgate. Aparentemente, o script de ataque deve ter sido um arquivo em lotes que é o inverso disso e adicionado .encrypteda todos os arquivos.
AwokeKnowing
1
votou porque você mencionou a unidade, caminho e extensão ( %% ~ df %% ~ pf %% ~ nf ) que mais se assemelha à saída de %% f da pergunta original, em vez de apenas o nome do arquivo sem extensão ( %% ~ nf )
ehambright
5

Estou usando isso se eu simplesmente desejar remover a extensão de uma variável (sem fazer loop de nenhum diretório ou arquivo existente):

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

Se você deseja remover a extensão de um caminho completo, use %%dpnf:

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

Exemplo:

(Use diretamente no console)

@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
fonte
0

Usando o 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
fonte
0

Se a sua variável for um argumento, você pode simplesmente usar %~dpnseguido pelo número do argumento, para não ter que se preocupar com comprimentos de extensão variáveis.

Por exemplo %~dpn0, retornará o caminho do arquivo em lotes sem sua extensão, %~dpn1ficará %1sem extensão, etc.

Martin Braun
fonte