【问题标题】:Batch to rename files using substring in filename使用文件名中的子字符串批量重命名文件
【发布时间】:2018-07-12 09:40:11
【问题描述】:

如果可能,我希望创建一个批处理文件,该批处理文件可以通过一个充满看似随机文件名的文件夹,并使用每个文件名中存在的子字符串重命名它们。命名约定似乎非常随机,但在每个文件名中存在一个“a”后跟 2 位数字,然后是“b”后跟 2 位数字 (a##b##)。这些值都不匹配,因此您不必担心生成的文件名相互冲突。

before:
left.process.a11b22.Feb.11
maid island a22b33 Mar 12
charm.dinner.a12b34.Jun.13
motivation blame a00b00 Nov 14
laser.activate.a99b99.Oct.15

我只想将这些重命名为更易于管理的内容,以保持相关值的一致性。理想情况下,将它们重命名为文件夹名称,后跟子字符串。

Ideal result:
Folder Name a00b00
Folder Name a11b22
Folder Name a12b34
Folder Name a22b33
Folder Name a99b99

这已经问了很多,这并不重要,但如果它可以递归完成,那将节省一个额外的步骤。甚至可能忽略名称中没有子字符串的任何文件。但是,我从来没有遇到过可以递归重命名的批次,考虑到每个单独的文件夹名称。无论如何,提前谢谢。

【问题讨论】:

  • 所以看起来您的子字符串始终是文件名的第三部分,由空格或句点分隔。
  • 不,我只是想出了一些随机的例子。它总是在中间的某个地方,但它并不总是从开始的第三个或从最后的第二个/第三个。这就是它如此棘手的原因。我什至不确定我的请求是否可行,但那里有比我更聪明的人,所以我想我会问。
  • 有可能。 Dave Benham 编写了一个名为 JRename 的混合批处理文件。他在 DosTips.com 论坛上维护代码。

标签: batch-file


【解决方案1】:

我希望这是您正在寻找的:

@ECHO OFF
SETLOCAL EnableDelayedExpansion



REM **************************************************

REM Source directory
SET source=C:\adjust\path

REM **************************************************



FOR /R "%source%" %%G IN ("*a??b??*") DO (
    SET "file_name=%%~nG"
    SET "counter=0"
    SET "error=0"
    ECHO !file_name! | FINDSTR /B /R "a[0-9][0-9]b[0-9][0-9]" >nul || CALL :get_file_name
    ECHO !file_name! | FINDSTR /I /B /R "a[0-9][0-9]b[0-9][0-9]" >nul && FOR %%H IN ("%%~dpG.") DO (SET "folder_name=%%~nxH") && REN "%%G" "!folder_name! - !file_name!%%~xG"
    IF "%error%"=="1" (ECHO Error: Cannot rename %%G^^!) ELSE (ECHO !folder_name! - !file_name!%%~xG)
)

ECHO Done^^!
PAUSE
EXIT


:get_file_name
IF !counter! LSS 10 (SET /A "counter=!counter!+1") ELSE (SET "error=1" & EXIT /B)
SET file_name=!file_name:*a=a!
ECHO !file_name! | FINDSTR /B /R "a[0-9][0-9]b[0-9][0-9]" >nul || SET file_name=!file_name:~1! || GOTO get_file_name
SET file_name=!file_name:~0,6!
EXIT /B

a[0-9][0-9]b[0-9][0-9] 方案匹配的每个文件都将重命名为folder_name - a[0-9][0-9]b[0-9][0-9](如果您不想要-,只需调整REN 命令)。


对于a??b??A??b??A??B??a??B?? 方案的区分大小写重命名:

@ECHO OFF
SETLOCAL EnableDelayedExpansion



REM **************************************************

REM Source directory
SET source=C:\adjust\path

REM **************************************************



FOR /R "%source%" %%G IN ("*a??b??*") DO (
    SET "file_name=%%~nG"
    SET "counter=0"
    SET "error=0"
    ECHO !file_name! | FINDSTR /R "a[0-9][0-9]b[0-9][0-9] a[0-9][0-9]B[0-9][0-9]" >nul && CALL :small_a
    ECHO !file_name! | FINDSTR /R "A[0-9][0-9]b[0-9][0-9] A[0-9][0-9]B[0-9][0-9]" >nul && CALL :capital_a
    ECHO !file_name! | FINDSTR /I /B /R "a[0-9][0-9]b[0-9][0-9]" >nul && FOR %%H IN ("%%~dpG.") DO (SET "folder_name=%%~nxH") && REN "%%G" "!folder_name! - !file_name!%%~xG"
    IF "%error%"=="1" (ECHO Error: Cannot rename %%G^^!) ELSE (ECHO !folder_name! - !file_name!%%~xG)
)

ECHO Done^^!
PAUSE
EXIT


:small_a
IF !counter! LSS 10 (SET /A "counter=!counter!+1") ELSE (SET "error=1" & EXIT /B)
SET file_name=!file_name:*a=a!
ECHO !file_name! | FINDSTR /I /B /R "a[0-9][0-9]b[0-9][0-9]" >nul || SET file_name=!file_name:~1! || GOTO small_a
SET file_name=!file_name:~0,6!
EXIT /B

:capital_a
IF !counter! LSS 10 (SET /A "counter=!counter!+1") ELSE (SET "error=1" & EXIT /B)
SET file_name=!file_name:*A=A!
ECHO !file_name! | FINDSTR /I /B /R "A[0-9][0-9]b[0-9][0-9]" >nul || SET file_name=!file_name:~1! || GOTO capital_a
SET file_name=!file_name:~0,6!
EXIT /B

这应该不会比第一个解决方案花费太多时间。


编辑:

02/02/18:

现在应该更快了。谢谢@Squashman

03/02/18:

添加了区分大小写的重命名、错误和成功输出以及计数器以防止无限循环。

05/02/18:

固定变量编辑。


如果您想使用其他方案,只需调整Variable EditFINDSTR 和/或Substring 位。

【讨论】:

  • 如果您这样做,就很容易获得父文件夹名称。 FOR %%H IN ("%%~dpG.") DO set "parent=%%~nxH"
  • 当,这工作得很好。我也确信我可以调整它以适应我在其他情况下的需要。肯定有一些部分让我头疼,但做得很好。
  • 很高兴能帮上忙!如果你对它的工作方式感兴趣,你可能想冒险看看这个:Variables: extract part of a variable (substring)"FOR" variable referencesFINDSTRRedirection/Pipes! :)
  • 非常感谢你们俩的努力。他们最新版本的批次对我不起作用。我在查看编辑历史时玩弄它,直到我更改了 SET file_name=!file_name:*a=a!回到 SET file_name=!file_name:~1!我不确定这些行是什么意思,但它似乎有效。
  • 我刚刚发现,有时在这些子目录中,它是否使用 a##b## 或大写版本 (A##B##) 会不一致,并且批处理会有点挂起.有没有办法通过它不区分大小写?或者它以某种方式将所有大写版本重命名为小写?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-27
  • 1970-01-01
  • 2013-12-18
  • 1970-01-01
  • 2012-05-04
  • 2013-12-19
相关资源
最近更新 更多