如何删除文件名开头的数字?

时间:2019-01-05 17:48:10

标签: batch-file

我需要将7612372 filename 50x50.jpg这样的文件名重命名为filename 50x50.jpg,删除文件名开头的所有数字。 位数可以是可变的。

我需要将其集成到从Windows命令提示符运行的现有批处理文件中。

4 个答案:

答案 0 :(得分:0)

如果该文件夹中所有文件的文件名格式与所有相同,则可以尝试:

@echo off

for /F "delims=" %%A IN ('dir /b /A-D') do (
    for /F "tokens=2-3" %%B IN ("%%A") do (
        ren "%%~fA" "%%B %%C"
    )
)

这是最短的方法,但不是最准确的方法。这是不安全的,因为如果filename包含空格,则文件将被错误地重命名。我为任务建议以下代码:

@echo off
setlocal EnableDelayedExpansion

for /F "delims=" %%A IN ('dir /b /A-D') do (
    set filename=%%A
    for /F "tokens=1" %%B IN ("%%A") do (
        ren "%%~fA" "!filename:%%B =!"
    )
)

更准确,并且只要文件具有开头提到的格式,就可以正确地重命名所有文件。

  • @echo off关闭关闭命令
  • setlocal EnableDelayedExpansion启用delayed expansion。我们这里仅使用,因为我们必须在for循环(代码块)中访问变量。您必须始终在这些代码块内使用延迟扩展。
  • 现在,我们进行一个for循环,以解析/F命令的输出dir /b /A-D),该命令列出了当前工作目录({{ 1}}),不包括目录%cd%)。
    • 我们需要在此处使用文件名设置一个变量。我们可以使用循环的变量名(/A-D,但是变量有一个优势:%%A,甚至我们这里需要的%var:search=replace%
    • 现在,我们进行另一个!var:search=replace!循环以解析字符串for):文件名(/F)。我们需要访问第一个令牌以在以后减去它。我们实际上并不需要在这里指定它,但是最好使它更清楚。
      • 我们现在重命名文件:%%A是当前处理的文件名所在的完整路径,而%%~fA表示采用!filename:%%B =!环境变量,搜索字符串filename(第一部分)文件名[数字]和空格),然后将其替换为空字符串;其实什么都没有!

答案 1 :(得分:0)

对于此任务,我建议使用以下批处理代码:

@echo off
for /F "delims=" %%A in ('dir "* *" /A-D-H /B 2^>nul') do for /F "tokens=1*" %%B in ("%%A") do ren "%%A" "%%C"
pause

FOR 命令与cmd.exe /C(更精确的%ComSpec% /C)一起在后台命令行的单独命令进程中运行:

dir "* *" /A-D-H /B 2>nul

DIR 输出以处理此后台命令过程的 STDOUT

  • 仅由于选项/A-D-H而具有所有未隐藏文件的名称(属性不是目录,也不是隐藏的)
  • 由于选项/B没有文件路径而以裸格式显示
  • 匹配通配符模式* *,该通配符模式匹配任何文件名且内部至少有一个空格
  • 在当前目录中,该目录可以但不能是批处理文件的目录。
如果

DIR 找不到符合这些条件的任何目录条目,则会输出一条错误消息来处理 STDERR 。此错误消息将重定向到设备 NUL 进行抑制。

阅读有关Using Command Redirection Operators的Microsoft文章,以获取2>nul的解释。当Windows命令解释器在执行命令之前处理此命令行时,重定向操作符>必须在 FOR 命令行上使用脱字符号^进行转义,才能被解释为文字字符。 FOR ,它将在后台启动的单独命令进程中执行嵌入式dir命令行。

FOR 捕获所有输出的行以处理已启动命令过程的 STDOUT ,并在启动cmd.exe自身终止后处理这些行。对于此文件重命名任务而言,非常重要的一点是,在对文件进行重命名之前, FOR 会在捕获的文件名列表上运行,因为否则,在 FOR 访问它们时目录条目将会更改。因此,在这种情况下无法直接使用for,因为for将处理* *目录条目的列表,而此列表在每次成功重命名文件时都会更改。结果将是文件没有多次重命名或重命名,甚至是一个无限循环的循环,具体取决于文件系统(NTFS或FAT32或ExFAT等FAT文件系统)。

带有选项/F

FOR 会忽略此处未出现的空行。 FOR 也忽略以分号开头的行,因为默认行号为eol=;。但是 DIR 输出的所有行都应以数字开头,因此,可以保留此任务的默认行尾定义。

带有选项/F

FOR 默认情况下使用常规空格和水平制表符作为分隔符将行拆分为子字符串,并仅将第一个空格/制表符分隔的字符串分配给指定的循环变量。在外部 FOR 循环中,不需要这种行拆分行为,因为循环变量A应该包含完整的文件名,并带有所有空格。因此,delims=用于定义一个空的定界符列表以禁用行拆分行为。更安全的是"delims= eol=",它也没有定义行尾字符。

分配给循环变量A的文件名在内部 FOR 循环中以%%A作为字符串引用,该文件将文件名分为两个子字符串(令牌)。第一个子字符串是分配给指定循环变量B的数字。第一个空格序列之后的第二个子字符串(文件名中不能使用制表符)被分配,而没有根据ASCII table进一步拆分到下一个循环变量C。换句话说,在文件名7612372 filename 50x50.jpg上,循环变量B保持7612372,并且filename 50x50.jpg被分配给循环变量C

命令 REN 通过将分配给循环变量A的完整文件名引用到分配给循环变量C的第一个空格之后的部分来重命名文件。

最后添加了命令 PAUSE ,以查看文件重命名失败时命令 REN 输出的错误消息。除了可以成功重命名所有文件上的 PAUSE 提示以外,没有任何输出。

使用 FINDSTR 作为过滤器,可以进一步增强批处理代码,以确保使用以下代码,重命名的文件实际上以一位或多位数字开头直到第一位:

@echo off
for /F "delims=" %%A in ('dir "* *" /A-D-H /B 2^>nul ^| %SystemRoot%\System32\findstr.exe /R /C:"^[0123456789][0123456789]* "') do for /F "tokens=1*" %%B in ("%%A") do ren "%%A" "%%C"
pause

将名称为03T30 NAME T ALL 40X40X2 - Copy.JPG的文件重命名为T30 NAME T ALL 40X40X2 - Copy.JPG的另一种变体:

@echo off
for /F "delims=" %%A in ('dir /A-D-H /B 2^>nul ^| %SystemRoot%\System32\findstr.exe /R "^[0123456789][0123456789]*"') do for /F "tokens=* delims=0123456789 " %%B in ("%%A") do ren "%%A" "%%B"
pause

DIR 输出当前目录中所有非隐藏文件的名称。此输出将重定向为 FINDSTR 的输入,该输入将检查文件名是否以一位或多位数字开头。仅那些文件名输出到后台命令进程的 STDOUT 中,然后由 FOR 处理。

内部的 FOR 将所有数字和空格字符解释为字符串定界符,原因是delims=0123456789 ,并且将数字或空格的第一个序列后的所有内容分配给循环变量B,原因是{ {1}}。因此,循环变量tokens=*保留B,其中filename 50x50.jpg分配给7612372 filename 50x50.jpgA的文件名T30 NAME T ALL 40X40X2 - Copy.JPG

要了解所使用的命令及其工作方式,请打开命令提示符窗口,在其中执行以下命令,并非常仔细地阅读每个命令显示的所有帮助页面。

  • 03T30 NAME T ALL 40X40X2 - Copy.JPG
  • dir /?
  • echo /?
  • findstr /?
  • for /?
  • pause /?

PS:我建议使用共享软件文件管理器Total Commander,它具有内置的重命名工具,可以为没有编码经验的人重命名文件和文件夹。下载,安装并启动Total Commander,导航到包含所有这些文件的文件夹,按 Ctrl + A 选择文件,按 Ctrl + M 打开多重重命名工具窗口,其余的不言而喻。但是,如果您仍需要帮助,请按 F1 键以打开多重命名工具的帮助页面。

答案 2 :(得分:0)

您的问题不够具体,无法为我们提供解决方案,您确实需要提供希望将其集成到其中的代码部分。

这个问题只需要一个文件,就像您的问题一样,该文件必须以您指定的格式命名,即所需部分与不需要的部分之间用空格隔开:

import urllib as ur

def downloader(x):
    "Imagine we will call downloader with given seed url 
    for example site.com/seq-{}-signature=xxxxxx
    in there program will change number with format like that
    site.com/seq-1-signature=xxxxxx
    site.com/seq-2-signature=xxxxxx and so on.."
    for i in range(1,2000):
        try:
            "video will created with given namber like -> : 1.ts , 2.ts"
            ff=open("{}.ts".format(i),'wb')
            "and part of video will be read with url and write to file"
            ff.write(x.urlopen(x.format(i)).read())
            ff.close()
        except Exception:
            continue

>>>downloader('examp.ple/seq-{}-ddadadaad')

[编辑/]

我从您的评论中注意到,您确实希望解析多个文件,而这些文件与您在问题中提供的命名方案不匹配。

因此,这是基于那些更改的参数的更新的潜在解决方案。

@Set "name=7612372 filename 50x50.jpg"
@Ren "%name%" "%name:* =%"

向LotPings致歉,我注意到他们发布了非常相似的方法/解决方案

答案 3 :(得分:0)

一种更简单的解决方案是使用

  • 所有数字和空格为delim和
  • tokens = *

:: Q:\Test\2019\01\06\SO_54054587.cmd
for /F "delims=" %%A in (
    'dir "* *" /A-D-H /B 2^>nul'
) do for /F "tokens=* delims=0123456789 " %%B in (
    "%%A"
) do ren "%%A" "%%B"

这将删除所有前导定界符,而分割文件名的其余部分。

与其他答案一样,这不能说明已经存在的文件名短。