批处理-使用通配符路径重命名文件



最近我开始工作,我的第一个任务是写一个批处理文件,自动将文件名更改为filename_date,并使用原始文件结尾。为此,您应该能够将路径写入文本文件(例如paths.txt),并且当您启动程序时,它应该从那里取任意行(=path->file)并重新命名它。我让它在我的PC上工作得很好,但当我把它交给测试时,他们要求使用通配符Z:Path*.*。我当前的代码如下所示:

@echo off
setlocal EnableDelayedExpansion
cd %~dp0    
For /F "tokens=*" %%m in (paths.txt) do (
set path=%%~dpm
set name=%%~nxm
pushd "!path!"
dir
For /r !path! %%f in (!name!) do (
set path=%%~dpf
set name=%%~nf
set ending=%%~xf
set datsave=%%~nxf
set "name=!name!_"
set "name=!name!!date:~6,4!"
set "name=!name!!date:~3,2!"
set "name=!name!!date:~0,2!"
set "name=!name!!ending!"
copy "!datsave!" "!name!"
del "!datsave!"
cls
popd
)
)

我知道很多可能更容易和更有效的做,但这是我的第一批项目,我很高兴除了通配符问题。举个例子:C:SomePath*.*

这一行应该在paths.txt中。使用分隔

set path=%%~dpf
set name=%%~nf
set ending=%%~xf
set datsave=%%~nxf

得到如下结果:

path: C:SomePath
name: C:SomePath
ending: -empty-
datsave: C:SomePath

,因为name在第一个for循环开始时被设置为Path。但是,如果我不使用通配符,这似乎是工作的。

现在的问题是:为什么会发生这种情况,我如何摆脱它?还是我用错了通配符?

再次:这是我第一次使用批处理,所以它可能是一些简单的;)

好了,我解决了两个问题,现在可以运行了

set name=%%~nxm计算通配符。即使name是*.txt,它也会返回bar.txt。我用一个basename计算代替了它:set name=!name:*=!做了足够多的次数(不是很微妙,但他们批处理文件迫使我们做这样的事情),保留通配符

另一个问题是for /R loop:在pushd之后,参数需要是.,否则不会被扫描。

最后一个小错误:使用rename代替copy + delete。它保存文件时间,非常快。复制然后删除一个大文件可能需要很长时间。

@echo off
set DEPTH=20
setlocal EnableDelayedExpansion
cd %~dp0    
For /F %%m in (paths.txt) do (
set pth=%%~dpm
set z=%%m
set name=!z!
rem brutal basename. We cannot break the inner loop or
rem it would break the upper loop too
for /L %%I in (1,1,%DEPTH%) do set name=!name:*=!
rem but we can check if it is really a basename
set chkname=!name:*=!
if not !chkname!==!name! ( echo please increase DEPTH value
pause
exit /B)
rem set name=%%~nxm
pushd "!pth!"
For /r . %%f in (!name!) do (
set pth=%%~dpf
set name=%%~nf
set ending=%%~xf
set datsave=%%~nxf
set "name=!name!_!date:~6,4!!date:~3,2!!date:~0,2!!ending!

echo renaming "!datsave!" to "!name!"
rem ren "!datsave!" "!name!"
popd
)
)
  • paths.txt只包含一行C:fullpathtotest*.txt
  • 我的test目录包含2个文本文件和1个其他文件
输出:

renaming "bar.txt" to "bar_20160812.txt"
renaming "foo.txt" to "foo_20160812.txt"

(只需取消ren行注释即可完成工作)

Weeeeell首先再次感谢@ jean - franois Fabre和@aschipfl对我的耐心。在第二个批处理文件提示之后,我不得不测试一些事情,因为不是所有事情都工作得很好,但现在一切都工作得很好!

主文件代码:

@echo off
setlocal EnableDelayedExpansion
cd %~dp0
set DEPTH=20
For /F %%m in (paths.txt) do (
pause
set pth=%%~dpm
  REM pushd !pth!
  REM set origpth=!cd!
  REM popd
set z=%%m
set name=!z!
For /L %%i in (1,1,%DEPTH%) do set 
name=!name:*=!
set chkname=!name:*=!
if not !chkname!==!name! ( echo depth to small
pause
exit /B)
rem set name=%%~nxm
pushd "!pth!"
For /r . %%f in (!name!) do (
pushd %~dp0
call renamefiles.bat %%f REM "!origpth!"
popd
)
)

子文件代码:

@echo off   
  REM set pth=%~dp1
  REM set origpth=%2
  REM set origpth=%origpath:"=%
  REM If !pth!==%origpth% (
set path=%~dp1
set name=%~n1
set ending=%~x1
set datsave=%~nx1
pushd !path!
set "name=!name!_!date:~6,4!!date:~3,2!!date:~0,2!!ending!"
pause
echo renaming "!datsave!" to "!name!"
rem "!datsave!" "!name!"
cls
popd
  REM )
编辑:经过测试,我想,子文件夹也包括在内!我把额外的代码加上REM和两个额外的空格。去掉这些REM,重命名时程序将不再包含子文件夹:)