我正在尝试编写一个BAT脚本,根据文件名将文件移动到子文件夹中 - 不需要详细说明这个文件的明确目的,这些文件以2个描述性前缀“PREFIX1_PREFIX2_descriptivefilename”命名 - 带有下划线分隔符
我想根据一些依赖于PREFIX1和PREFIX2的不同规则将文件移动到文件夹中。
这旨在用于组织打印文档和图像的内部系统,这些文档和图像打印在各种类型的纸张上。例如,假设我们只使用2种PREFIX1类型 - Class1和Class2。 PREFIX2可以采用多种形式表示纸张尺寸,简单来说,“A6paper”,“A5paper”,“A4paper”和“更大”。
我需要文件夹的文件名与前缀略有不同,因为任何一个文件夹都可以包含PREFIX1和PREFIX2文档类型的混合,因为打印类型数量有限,假设我们正在使用的文件夹是“A5”,“A4”,“其他”,带有A6paper和A5paper前缀的文件都将进入“A5”。
以下是我的示例BAT脚本:
for /f "tokens=1,2* delims=_" %%a in ('dir /B *_*_*.pdf *_*_*.png') do (
if /I %%a == Class1 (
if /I %%b == A4paper (
if not exist "A4" md "A4"
move "%%a_%%b_%%c" "A4\%%a_%%b_%%c"
)
else if /I %%b == A5paper (
if not exist "A5" md "A5"
move "%%a_%%b_%%c" "A5\%%a_%%b_%%c"
)
else if /I %%b == A6paper (
if not exist "A5" md "A5"
move "%%a_%%b_%%c" "A5\%%a_%%b_%%c"
)
else if /I %%b == Larger (
if not exist "Other" md "Other"
move "%%a_%%b_%%c" "Other\%%a_%%b_%%c"
)
)
else if /I %%a == Class2 (
if /I %%b == A4paper (
if not exist "A4" md "A4"
move "%%a_%%b_%%c" "A4\%%a_%%b_%%c"
)
else if /I %%b == A5paper (
if not exist "A5" md "A5"
move "%%a_%%b_%%c" "A5\%%a_%%b_%%c"
)
else if /I %%b == A6paper (
if not exist "A5" md "A5"
move "%%a_%%b_%%c" "A5\%%a_%%b_%%c"
)
else if /I %%b == Larger (
if not exist "Other" md "Other"
move "%%a_%%b_%%c" "Other\%%a_%%b_%%c"
)
)
else if....
因为你可以看到这段代码看起来有点笨拙。我真的不确定BAT的语法,是否应该完全删除“else”,因为我使用它会出现一些错误。无论如何,输出似乎与预期的一样,嵌套if子句中的代码似乎是随机执行的,无论更高级别的规则如何。
我还希望能够写出如下内容:
if /I %%b in ("A5paper", "A6paper") (
if not exist "A5" md "A5"
move "%%a_%%b_%%c" "A5\%%a_%%b_%%c"
)
......但似乎不允许这样做。
非常感谢任何帮助。
答案 0 :(得分:1)
for %%a in (A4 A5 Other) do md %%a 2>nul
for /f "tdelims=" %%r in ('dir /B *_*_*.pdf *_*_*.png') do (
for /f "tokens=1,2* delims=_" %%a in ("%%r") do (
if /i "%%a"== "Class1" (
if /i "%%b"=="A4paper" (move "%%r" "a4\" >nul)
if /i "%%b"=="A5paper" (move "%%r" "a5\" >nul)
if /i "%%b"=="A6paper" (move "%%r" "a5\" >nul)
if /i "%%b"=="Larger" (move "%%r" "Other\" >nul)
)
if /i "%%a"== "Class2" (
if /i "%%b"=="A4paper" (move "%%r" "a4\" >nul)
if /i "%%b"=="A5paper" (move "%%r" "a5\" >nul)
if /i "%%b"=="A6paper" (move "%%r" "a5\" >nul)
if /i "%%b"=="Larger" (move "%%r" "Other\" >nul)
)
)
)
)
您的问题似乎基本上属于逻辑问题,但在批处理中,必须放置任何else
,以便else
关键字前面的闭括号和后面的左括号都在相同的物理线。
从您的示例中,您会发现%%b
只能是A4paper
,A5paper
,A6paper
或Larger
。关键是它不能匹配多个这些值。同样适用于%%a
。
语法if "value"=="anothervalue" ...
可能更好,因为它可以确保处理值而不管任何会扰乱cmd
解析的分隔符(行间距)。
如果您首先创建所有目标目录,则无需在例程中创建它们,这简化了事务。
2>nul
会抑制错误消息(例如already exists
)>nul
会抑制正常消息(例如1 files(s) moved
)。
将文件名应用于%%r
是为了简化 - 内部for
可以按照显示的方式处理%%r
,%%r
可以方便地包含整个名称,因此它不需要重建。
同样,使用move
语句中的引号表示正确处理了spaces in filenames
。
答案 1 :(得分:1)
解决此问题的最简单,最有效的方法是通过array:您事先定义一系列数组元素,为每对PREFIX1和PREFIX2指定目标文件夹。之后,您只需使用数组数据处理文件:
@echo off
setlocal EnableDelayedExpansion
rem Define the array for destination folders:
set "folder[Class1,A4paper]=A4"
set "folder[Class1,A5paper]=A5"
set "folder[Class1,A6paper]=A5"
set "folder[Class1,Larger]=Other"
set "folder[Class2,A4paper]=A4"
set "folder[Class2,A5paper]=A5"
set "folder[Class2,A6paper]=A5"
set "folder[Class2,Larger]=Other"
rem Move the files:
for /F "tokens=1,2* delims=_" %%a in ('dir /B *_*_*.pdf *_*_*.png') do (
if not exist "!folder[%%a,%%b]!" md "!folder[%%a,%%b]!"
move "%%a_%%b_%%c" "!folder[%%a,%%b]!\"
)
您无需在move
命令中重复文件名。
有关批处理文件中阵列管理的进一步说明,请参阅:Arrays, linked lists and other data structures in cmd.exe (batch) script