Rename Files using wildcard paths

限于喜欢 提交于 2019-12-07 10:44:54

问题


Recently I started working and my first task is to write a batch file that automatically changes filenames to filename_date with the original file-ending. For that you should be able to write paths into a textfile (e.g. paths.txt) and when you start the program, it should take any line (=path->file) from there and rename it. I got it to work on my PC quiet well but as I gave it to testing they asked to make the use of wildcards Z:\Path\*.* possible. My current code looks as follows:

@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
)

)

I know that a lot of it is probably easier and more efficient to do, but this is my first batch project and I am quiet happy except for the wildcard problem. So an example would be: C:\Some\Path\*.*

This line would be in paths.txt. With the splitting

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

I get the following:

path: C:\Some\Path
name: C:\Some\Path
ending: -empty-
datsave: C:\Some\Path

because name is set to the Path at the start of the first FOR-Loop. But that seems to be working if I do not use wildcards.

Now the question: Why does this happen and how do I get rid of it? Or do I just use the wrong type of wildcards?

Again: This is my first time I work with batch, so it might be something simple ;)


回答1:


Ok, I figured out 2 problems and now it works

set name=%%~nxm evaluates the wildcard. Even if name is *.txt it will return bar.txt. I replaced that by a basename computation instead: set name=!name:*\=! done enough times (not very subtle but hey batch files forces us to do such things) which preserves the wildcard

The other problem is the for /R loop: after pushd, the argument needs to be . or it won't be scanned.

Last minor one: use rename instead of copy plus delete. It preserves file time and is very fast. Copying then deleting a large file can take a long time.

@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 contains just a line C:\full\path\to\test\*.txt
  • my test directory contains 2 text files and 1 other file

output:

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

(just uncomment the ren line to get the job done)




回答2:


Weeeeell First of all thanks again to @Jean-François Fabre and @aschipfl for their patience with me :) After the hint with the second batch file I had to test a few things as not everything worked as fine, but now everything works great!

Code of the Main file:

@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
)

)

And the code of the sub-file:

@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 )

EDIT: After testing around a bit I figured, that subfolders are included as well! I put extra code to both codes marked with REM and two extra spaces. Take out those REM's and the programm will not longer include subfolders when renaming :)



来源:https://stackoverflow.com/questions/38911430/rename-files-using-wildcard-paths

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!