接着上一个问题:PowerShell/Batch script to rename each file to include original name + folder name
几个月以来,我具有以下文件夹结构:
2017
│
├─April reports
│ ├─01-04-2018
│ │ ├─XYZAPPROVED123.pdf
│ │ ├─XYZAPPROVED123_V2.pdf
│ │ └─XYZUNAPPROVED123.pdf
│ │
│ ├─02-04-2018
│ │ ├─XYZAPPROVED123.pdf
│ │ └─XYZUNAPPROVED123.pdf
│ │
│ │
│ └─30-04-2018
│ ├─XYZAPPROVED123.pdf
│ └─XYZUNAPPROVED123.pdf
│
├─ May reports
│ ├─01-04-2018
│ │ ├─XYZAPPROVED123.pdf
│ │ ├─XYZAPPROVED123_V2.pdf
│ │ └─XYZUNAPPROVED123.pdf
│ │
│ ├─02-04-2018
│ │ ├─XYZAPPROVED123.pdf
│ │ └─XYZUNAPPROVED123.pdf
│ │
│ │
│ ├─30-04-2018
│ ├─XYZAPPROVED123.pdf
.
.
.
├─December reports (etc)
一个月中每一天的每个文件夹都包含一个具有相同名称(“ XYZAPPROVED123”或“ XYZUNAPPROVED123”)的批准和未批准的报告。有些包含V2。
我想重命名每个名称,以便删除“ 123”,并将文件夹名称(日期)包含在文件名中,例如“ XYZAPPROVED_01-04-2018”。我不想将文件名完全替换为文件夹的名称,我只想在可能的情况下将其添加在末尾,并用下划线分隔。
完成此操作后,我想删除名称中包含“ XYZUNAPPROVED”的所有文件,并删除同一文件夹中存在“ XYZAPPROVED_V2”的所有“ XYZAPPROVED”文件(版本2取代了原始)。
我已成功使用以下脚本获取了一个批处理脚本,可用于一个月(4月)的报告。我遇到的问题是添加了一个附加循环,以便我可以在所有月份中运行它。
4月脚本(有效):
@echo off
cd "<actual path>"
for /D %%I in ("<actual path>\????-??-??") do (
for %%J in ("%%I\XYZ*.pdf") do (
if exist "%%I\XYZUN*" del /F "%%I\XYZUN*.pdf"
if exist "%%I\%%~nJ_V*.pdf" ( del "%%J" ) else ren "%%J"
"%%~nJ_%%~nI.pdf"
)
)
所有月份的脚本-(运行时什么都没发生)
@echo off
cd "<actual path>"
for /D %%H in ("<actual path>") do (
rem Enter into the month name folder
rem process each date
for /D %%I in ("%%H\????-??-??") do (
for %%J in ("%%I\XYZ*.pdf") do (
if exist "%%I\XYZUN*" del /F "%%I\XYZUN*.pdf"
if exist "%%I\%%~nJ_V*.pdf" ( del "%%J" ) else ren "%%J" "%%~nJ_%%~nI.pdf"
)
)
)
我想念什么?
答案 0 :(得分:2)
这是一种可以实现您想要的解决方案-请参阅所有说明性注释(data Expr = BinaryOperation BinaryOperator Expr Expr
| UnaryOperation UnaryOperator Expr
| Literal LiteralValue
| Variable Id
data BinaryOperator = Add | Sub | Mul | Div
data UnaryOperator = Not | Negate
):
rem
此脚本从与每天相关的子目录中删除以下文件:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "_ROOT=%~dp0TEST" & rem // (path of the root directory)
set "_DIR1=????" & rem // (mask for level-1 sub-directories (year))
set "_DIR2=* reports" & rem // (mask for level-2 sub-directories (month))
set "_DIR3=??-??-????" & rem // (mask for level-3 sub-directories (day))
set "_NAMEREN=approved" & rem // (partial name of files to keep)
set "_NAMEDEL=unapproved" & rem // (partial name of files to delete)
set "_MASKREN=*%_NAMEREN%*" & rem // (name pattern for files to keep)
set "_MASKDEL=*%_NAMEDEL%*" & rem // (name pattern for files to delete)
set "_FILEEXT=.pdf" & rem // (name extension for all files to process)
set "_VERSUFF=V" & rem // (beginning of version suffix in file names)
set "_KEEPSUFF=#" & rem // (set non-empty to keep version suffix)
rem // Build search string for version suffix:
set "SEARCH=_%_VERSUFF%[0123456789][0123456789]*"
rem // Walk through all level-1 sub-directories:
for /D %%C in ("%_ROOT%\%_DIR1%") do (
rem // Walk through all level-2 sub-directories:
for /D %%D in ("%%~C\%_DIR2%") do (
rem // Walk through all level-3 sub-directories:
for /D %%E in ("%%~D\%_DIR3%") do (
rem // Loop through all files to delete:
for %%F in ("%%~E\%_MASKDEL%%_FILEEXT%") do (
rem // Delete current file:
del "%%~F"
)
rem // Store path and name of current sub-directory:
set "LOC=%%~E" & set "SUB=%%~nxE"
rem // Loop through cached and sorted list of all files to potentially keep:
for /F "delims= eol=|" %%F in ('
2^> nul dir /B /A:-D /O:N "%%~E\%_MASKREN%%_FILEEXT%"
') do (
rem // Store file name and extension:
set "VER=" & set "FILE=%%~nF" & set "EXT=%%~xF"
rem // Check if current file name has got a version suffix:
echo(%%~nF| > nul findstr /I /E "%SEARCH%" && (
rem // Version suffix encountered, hence extract it:
setlocal EnableDelayedExpansion
for %%H in ("!FILE:_=" "!") do (
endlocal
set "VER=_%%~H"
setlocal EnableDelayedExpansion
)
endlocal
rem /* Check whether there are other files with same name but with another
rem version suffix appended: */
for %%I in ("%%~E\%_MASKREN%_%_VERSUFF%*%_FILEEXT%") do (
rem // Filter for correct version suffix:
echo(%%~nI| > nul findstr /I /E "%SEARCH%" && (
rem // Extract version suffix:
set "NUM=" & set "TEST=%%~nI"
setlocal EnableDelayedExpansion
for %%J in ("!TEST:_=" "!") do (
endlocal
set "NUM=_%%~J"
setlocal EnableDelayedExpansion
)
rem /* Check whether the other version suffix is higher (or equal)
rem than the one of the current file:
if !VER:*_%_VERSUFF%^=! lss !NUM:*_%_VERSUFF%^=! (
rem // Other version suffix is higher, so delete current file:
if exist "!LOC!\!FILE!!EXT!" del "!LOC!\!FILE!!EXT!"
)
endlocal
)
)
) || (
rem /* No version suffix encountered, hence check if there is a file with
rem the same name but with a version suffix appended: */
for %%G in ("%%~E\%%~nF_%_VERSUFF%*%%~xF") do (
rem // Filter for correct version suffix:
echo(%%~nG| > nul findstr /I /E "%SEARCH%" && (
rem // Delete current file as there is a newer version:
if exist "%%~E\%%~F" del "%%~E\%%~F"
)
)
)
rem // Check whether current file has been deleted:
if exist "%%~E\%%~F" (
rem // Keep version suffix only if desired:
if not defined _KEEPSUFF set "VER="
rem // Extract the partial file name to keep:
setlocal EnableDelayedExpansion
for /F "delims=| eol=|" %%K in ("_!FILE:%_NAMEREN%=|!") do (
endlocal
set "NAME=%%K%_NAMEREN%"
setlocal EnableDelayedExpansion
)
rem // Rename kept file as desired:
ren "!LOC!\!FILE!!EXT!" "!NAME:~1!_!SUB!!VER!!EXT!"
endlocal
)
)
)
)
)
endlocal
exit /B
的所有*.pdf
文件; unapproved
的{{1}}文件,但没有版本后缀*.pdf
,以防其他approved
文件带有_V
但附加了版本后缀; *.pdf
且版本后缀为approved
的{{1}}个文件,其后缀的版本号不是遇到的最大版本号; 该脚本会在与每日相关的子目录中保留并重命名以下文件:
*.pdf
且版本后缀为approved
的{{1}}文件,其附加版本号是遇到的最大版本号;保留_V
之前的部分,之后的部分由*.pdf
加上父目录名称替换;版本后缀可以选择保留(请参见常量approved
); 答案 1 :(得分:1)
这是this answer中最后一个批处理文件,由于新要求在批处理文件顶部定义的每个文件名的开头都带有固定前缀而被重写。
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "Prefix=XYZ"
for /F "delims=" %%I in ('dir "%~dp0%Prefix%Approved*.pdf" /A-D-H /B /S 2^>nul') do call :ProcessFile "%%I"
endlocal
rem Avoid a fall through to the subroutine.
goto :EOF
rem The subroutine ProcessFile first assigns full qualified file name
rem of found approved PDF file to environment variable FullFileName.
rem All occurrences of defined prefix after a backslash are substituted
rem by backslash, defined prefix and additionally the two characters UN.
rem A PDF file with that name in same directory as the found approved PDF
rem is deleted if existing which means there is still an unapproved PDF
rem file for an already approved PDF file.
rem Next the subroutine checks if there is one more approved PDF file
rem starting with same name, but there is additionally _V and any other
rem string in which case the approved PDF file without _V* in name is
rem deleted and subroutine is exited.
rem Otherwise the subroutine assigns path of passed file name ending with
rem a backslash to environment variable FilePath. Next the backslash is
rem removed from file path. Then is checked if the file path ends with
rem folder name "dayreports" in which case also this folder is removed
rem from file path. The file path is processed by command FOR to get
rem the string after last backslash referenced with %%~nxJ which is the
rem name of the folder of which name should be in new file name. Before
rem moving the file with new name containing the date, it is checked if
rem the current file name ends already with an underscore and the name
rem of the folder which should be the date. The subroutine is exited
rem if this condition is true to avoid double processing an already
rem processed file in a previous execution of this batch file.
:ProcessFile
setlocal EnableDelayedExpansion
set "FullFileName=%~1"
set "UnapprovedFile=!FullFileName:\%Prefix%=\%Prefix%Un!"
if exist "%UnapprovedFile%" del /F "%UnapprovedFile%"
endlocal
if exist "%~dp1\%~n1_V*%~x1" (
del /F %1
goto :EOF
)
set "FilePath=%~dp1"
set "FilePath=%FilePath:~0,-1%"
if /I "%FilePath:~-11%" == "\dayreports" set "FilePath=%FilePath:~0,-11%"
for %%J in ("%FilePath%") do set "FolderName=%%~nxJ"
set "FileName=%~n1"
if "%FileName:~-11%" == "_%FolderName%" goto :EOF
move /Y %1 "%FilePath%\%~n1_%FolderName%%~x1" >nul
goto :EOF
有一个非常简单的方法可以删除目录树所有目录中的所有*unapproved*.pdf
文件,而与同一个目录中存在*approved*.pdf
文件无关:
del /A /F /Q /S "%~dp0*unapproved*.pdf"
带有已使用参数的命令 DEL 删除
/Q
而安静*unapproved*.pdf
而导致批处理文件及其所有子目录中的所有/S
*unapproved*.pdf
而将/F
设置为只读属性*unapproved*.pdf
在内的/A
由于setlocal
而设置了隐藏属性。可以先在批处理文件顶部的 FOR 之前使用此命令行来删除子例程endlocal
中的ProcessFile
... *unapproved*.pdf
块循环,可以更快地执行批处理文件。
我不建议删除所有*approved*.pdf
而不检查同一目录中是否有相应的#createBtn
。