批次:移除副档名


155

我有以下维基百科的批处理脚本:

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

在for循环中,所有带有扩展名flv的文件都会被回显,但是我希望对文件进行一些操作,在此,我需要一个不带扩展名的文件和一个带扩展名的文件。我怎么能得到这两个?

我搜索了解决方案,但找不到。我是一个真正的新手...

Answers:


309

您只能用于%%~nf获取文件名,如参考资料中所述for

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

提供以下选项:

带修饰符的变量说明

%〜I展开%I,这会删除所有周围的内容 
                        引号(“”)。
%〜fI将%I扩展为完全限定的路径名​​。
%〜dI仅将%I扩展为驱动器号。
%〜pI仅将%I扩展到路径。
%〜nI仅将%I扩展为文件名。
%〜xI仅将%I扩展为文件扩展名。
%〜sI将路径扩展为仅包含短名称。
%〜aI将%I扩展到file的文件属性。
%〜tI将%I扩展到文件的日期和时间。
%〜zI将%I扩展为文件大小。
%〜$ PATH:I搜索PATH环境中列出的目录 
                        变量并将%I扩展为的完全限定名称 
                        找到第一个。如果环境变量名称为
                        未定义或搜索未找到文件,
                        此修饰符扩展为空字符串。    

8
简要说明一下:在上面的示例中,%% f将类似于C:\Users\Admin\Ordner\foo.flv%%〜nf将为您提供foo。如果你想要的一切,除了扩展用%%〜DF %%〜PF %%〜NF这将使你C:\Users\Admin\Ordner\foo
ehambright

8
@ehambright后期评论,但我想使用%%~dpnf将是一个较短的选择。

感谢修改器/描述表Dirk。我的情况是%1在批处理脚本中从param获取不带扩展名的文件名。echo %~n1是我所追求的。
戴夫·派

26

如果您的变量保存的文件实际上不存在,则该FOR方法将不起作用。如果您知道扩展名的长度,可以使用一个技巧来获取一个子字符串:

%var:~0,-4%

-4装置,所述最后4位(推测.EXT)将被截断。


这对我不起作用(在Win8.1上)-可能echo %f:~0,-4%在问题中使用的示例上下文中尝试时可能会误解它。我究竟做错了什么?
狼2015年

2
显然,这适用于“普通”变量,而不适用于FOR变量(或者也许我只是不知道正确的语法)。无论如何,这将在OP示例的上下文中起作用:SET fl=%%f然后echo %fl:~0,-4%
Ohad Schneider

@Wolf,您需要将循环变量的值设置为普通变量,然后在普通变量中进行字符串替换/截断
phuclv

在很多情况下,扩展长度不等于3或未知。即使文件不存在,您仍然可以使用for,请参阅我的答案。
marsze

14

我也是Windows cmd的陌生人,但是请尝试以下操作:

echo %%~nf

8

这是一个很晚的响应,但是我想出了一个解决方案来解决DiskInternals LinuxReader在将'.efs_ntfs'附加到保存到非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

我不确定它是否回答了所提问题,但实际上对我有帮助,谢谢!
matan7890 2014年

1
@ matan7890是的; 操作没有指定“我希望对文件进行某些操作” [原文如此],但是这些操作之一可能是重命名它们,在这种情况下,我的答案是对已接受答案的扩展。
Agi Hammerthief 2014年

这帮助了我的一个朋友,他打开了一个附件并将其.encrypted添加到他的所有文件中,并要求支付赎金。显然,攻击脚本必须是与之相反的批处理文件,并且已添加.encrypted到所有文件中。
AwokeKnowing'Mar

1
之所以投票,是因为您提到了驱动器,路径和扩展名(%%〜df %%〜pf %%〜nf ),它与原始问题中%% f的输出非常相似,而不仅仅是不带扩展名的文件名(%% 〜NF
ehambright

5

如果我只是想从变量中删除扩展名(而不循环任何目录或现有文件),则使用此方法:

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

如果要从完整路径中删除扩展名,请%%dpnf改用:

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

例:

(直接在控制台中使用)

@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

0

使用cygwin bash进行切碎

  :: 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

0

如果您的变量是一个参数,则只需%~dpn在参数后面加上参数号即可,因此您不必担心扩展名长度的变化。

例如%~dpn0将返回该批处理文件的路径,不带扩展名,%~dpn1%1不带扩展等

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.