首页 > 解决方案 > 重命名文件时替换最后一个_

问题描述

我想在windows中删除所有「name.jpg」并将「name_.jpg」重命名为「name.jpg」。文件结构是这样的。

>upperFolder
  >p1
    >學生_二反田●雄.jpg
    >學生_二反田●雄_.jpg
    >學生_半田●男.jpg
    >學生_半田●男_.jpg
    >學生_潘●.jpg
    >學生_潘●_.jpg
    >...
  >...
  >p7
    >學生_石井節●.jpg
    >學生_石井節●_.jpg
    >學生_王裕●.jpg
    >學生_王裕●_.jpg
    >學生_●垣  勇.jpg
    >學生_●垣  勇_.jpg

删除p1/学生_二反田●雄.jpg

重命名p1/学生_二反田●雄_.jpg p1_学生-二反田●雄.jpg

最终结果如下所示。p1_ 是为了防止重复文件名和 - 单独的学生姓名。

>upperFolder
  >p1_學生-二反田●雄.jpg
  >p1_學生-半田●男.jpg
  >p1_學生-潘●.jpg
  >...
  >p7_學生-石井節●.jpg
  >p7_學生-王裕●.jpg
  >p7_學生-●垣  勇.jpg

我怎样才能在 bat 或 php 中做到这一点?

我试过了

mkdir tmp

for /f "eol=: delims=" %%D in ('dir /b /s /ad *^|sort /r') do (
  pushd "%%D"
  for %%F in (*) do move "%%F" "..\%%~nxD_%%F" >nul
  popd
)

move *_.jpg tmp
del *.jpg
cd tmp 
move *.jpg .. 2>NUL

但无法摆脱最后一个'_'

标签: batch-file

解决方案


CMD 中没有不匹配字符的通配符,因此您可以临时更改名称以 _ 结尾的文件的扩展名:

注意:如果您从批处理文件运行,请记住从 upperFolder 运行以下代码片段并将 %g 更改为 %%g。

:: /r stands for recursive and ~n stands for (file)name
for /r %g in (*_.jpg) do ren %g "%~ng.jphg"

然后您可以删除名称不以_结尾的文件:

del /s *.jpg

最后重命名并移动名称以_结尾的文件。但是你要求一些棘手的事情,那就是在文件名前面加上包含它的目录名,用 - 替换文件名的内部 _,删除文件名的尾随 _,然后将文件移动到 upperFolder:

:: so that the variable expansion inside for's works as expected
setlocal EnableDelayedExpansion
:: loop through all the directories and store the names in g
for /d %g in (*) do (
    for %h in ("%g\*_.jphg") do (
        set "newname=%~nh"
        :: remove trailing _
        set "newname=!newname:~0,-1!"
        :: replace ALL _ with -, assuming the filename only has one inner _
        set "newname=!newname:_=-!"
        :: prepend directory name and restore extension
        set "newname=%g_!newname!.jpg"
        :: rename and move to current directory
        move %h ".\!newname!"
    )
)

推荐阅读