使用通配符路径重命名文件
Rename Files using wildcard paths
最近我开始工作,我的第一个任务是编写一个批处理文件,自动将文件名更改为 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:\Some\Path\*.*
此行将在 paths.txt 中。
随着分裂
set path=%%~dpf
set name=%%~nf
set ending=%%~xf
set datsave=%%~nxf
我得到以下信息:
path: C:\Some\Path
name: C:\Some\Path
ending: -empty-
datsave: C:\Some\Path
因为名称设置为第一个 FOR 循环开始时的路径。但如果我不使用通配符,这似乎是可行的。
现在的问题是:为什么会发生这种情况,我该如何摆脱它?还是我只是使用了错误类型的通配符?
再说一遍:这是我第一次使用批处理,所以可能比较简单 ;)
好的,我解决了 2 个问题,现在可以了
set name=%%~nxm
评估通配符。即使名称是 *.txt
,它也会 return bar.txt
。
我用基本名称计算代替了它: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:\full\path\to\test\*.txt
- 我的
test
目录包含 2 个文本文件和 1 个其他文件
输出:
renaming "bar.txt" to "bar_20160812.txt"
renaming "foo.txt" to "foo_20160812.txt"
(只需取消注释 ren
行即可完成工作)
Weeeeell 首先再次感谢@Jean-François 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,重命名时程序将不再包含子文件夹:)
最近我开始工作,我的第一个任务是编写一个批处理文件,自动将文件名更改为 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:\Some\Path\*.*
此行将在 paths.txt 中。 随着分裂
set path=%%~dpf
set name=%%~nf
set ending=%%~xf
set datsave=%%~nxf
我得到以下信息:
path: C:\Some\Path
name: C:\Some\Path
ending: -empty-
datsave: C:\Some\Path
因为名称设置为第一个 FOR 循环开始时的路径。但如果我不使用通配符,这似乎是可行的。
现在的问题是:为什么会发生这种情况,我该如何摆脱它?还是我只是使用了错误类型的通配符?
再说一遍:这是我第一次使用批处理,所以可能比较简单 ;)
好的,我解决了 2 个问题,现在可以了
set name=%%~nxm
评估通配符。即使名称是 *.txt
,它也会 return bar.txt
。
我用基本名称计算代替了它: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:\full\path\to\test\*.txt
- 我的
test
目录包含 2 个文本文件和 1 个其他文件
输出:
renaming "bar.txt" to "bar_20160812.txt"
renaming "foo.txt" to "foo_20160812.txt"
(只需取消注释 ren
行即可完成工作)
Weeeeell 首先再次感谢@Jean-François 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,重命名时程序将不再包含子文件夹:)