简体   繁体   English

BAT脚本按文件名将文件移动到子文件夹中

[英]BAT script to move files into subfolders by file name

I am trying to write a BAT script to move files into subfolders depending on the filename - without going into too much detail about the explicit purpose of this, the files are named with 2 descriptive prefixes "PREFIX1_PREFIX2_descriptivefilename" - with an underscore delimiter. 我正在尝试编写BAT脚本,以根据文件名将文件移动到子文件夹中-无需过多地了解其显式目的,文件使用2个描述性前缀“ PREFIX1_PREFIX2_descriptivefilename”命名-带有下划线定界符。

I want to move the files into folders according to a few different rules which are dependent on both PREFIX1 and PREFIX2. 我想根据一些依赖于PREFIX1和PREFIX2的不同规则将文件移动到文件夹中。

This is intended to be used for an in-house system for organising printed documents and images, which are printed on a range of types of paper. 它旨在用于内部系统,以组织打印在各种纸张上的打印文档和图像。 For example's sake, lets say we are working with just 2 PREFIX1 types - Class1 and Class2. 例如,假设我们只使用2种PREFIX1类型-Class1和Class2。 PREFIX2 can take several forms denoting paper size, let's say for simplicity, "A6paper", "A5paper", "A4paper" and "Larger". PREFIX2可以采用几种表示纸张尺寸的形式,为简单起见,可以说是“ A6paper”,“ A5paper”,“ A4paper”和“ Larger”。

I need the folders to have slightly different filenames to the prefix as any one folder can contain a mix of both PREFIX1 and PREFIX2 document types, as there are a limited number of print types, let's say the folders we are working with are "A5", "A4", "Other", as files with the A6paper and A5paper prefix will both go into "A5". 我需要这些文件夹的文件名与前缀略有不同,因为任何一个文件夹都可以包含PREFIX1和PREFIX2文档类型的混合,因为打印类型的数量有限,比方说我们正在使用的文件夹为“ A5” ,“ A4”,“其他”,因为带有A6paper和A5paper前缀的文件都将放入“ A5”。

Here is my example BAT script: 这是我的示例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....

So as you can see this code is already a little unwieldy looking. 因此,如您所见,此代码看起来有些笨拙。 I am really not sure about the syntax of BAT, whether "else" should be removed entirely as I get some errors using this. 我真的不确定BAT的语法,因为在使用此错误时我是否应该完全删除“ else”。 Regardless however, the output seems to be nothing like that expected, the code in the nested if clauses seems to be executed randomly regardless of the higher level rules. 但是,无论如何,输出似乎都没有达到预期的效果,无论是否有更高级别的规则,嵌套if子句中的代码似乎都是随机执行的。

I would also ideally like to be able to write something like: 理想情况下,我还希望能够编写如下内容:

if /I %%b in ("A5paper", "A6paper") (
    if not exist "A5" md "A5"
    move "%%a_%%b_%%c" "A5\%%a_%%b_%%c"
)

...but this does not seem to be allowed. ...但这似乎是不允许的。

Any help would be much appreciated. 任何帮助将非常感激。

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

Your problems appear to be substantially ones of logic, but in batch, any else must be placed such that the close-parenthesis before the else keyword and the open-parenthesis after are all on the same physical line. 您的问题似乎基本上是逻辑上的问题,但必须成批地放置else任何问题,以使else关键字之前的else括号和后面的开放式括号都在同一物理行上。

From your example, you would observe that %%b can only be A4paper , A5paper , A6paper or Larger . 从您的示例中,您会发现%%b只能是A4paperA5paperA6paperLarger The point is that it can't match more than one of these values. 关键是它不能匹配多个这些值之一。 Same goes for %%a . %%a

The syntax if "value"=="anothervalue" ... is probably better since it will ensure that the values are processed regardless of any separators (line spaces) which would upset cmd 's parsing. if "value"=="anothervalue" ...的语法可能更好,因为它将确保对值进行处理,而不考虑任何会使cmd解析失败的分隔符(行空格)。

If you create all of the destination directories first, you don't need to create them within your routine, which simplifies matters. 如果首先创建所有目标目录,则无需在例程中创建它们,从而简化了事情。

The 2>nul suppresses error messages (like already exists ) The >nul suppresses normal messages (like 1 files(s) moved ). 2>nul禁止显示错误消息(例如already exists>nul禁止正常显示消息(例如1 files(s) moved )。

The application of the filename to %%r is to simplify - the inner for can process %%r in the manner shown, and %%r conveniently contains the entire name so it doesn't need to be reconstructed. 文件名的给应用%%r是简化-内for罐过程%%r中所示的方式,和%%r方便包含整个名称,以便它不需要被重建。

Again, using the quotes in the move statements means that spaces in filenames are correctly processed. 同样,在move语句中使用引号意味着spaces in filenames中的spaces in filenames已正确处理。

The simplest and most efficient way to solve this problem is via an array : you define in advance a series of array elements that specify the destination folder for each pair of PREFIX1 and PREFIX2. 解决此问题的最简单,最有效的方法是通过数组 :您预先定义了一系列数组元素,这些元素为每对PREFIX1和PREFIX2指定目标文件夹。 After that, you just process the files using the array data: 之后,您只需使用数组数据处理文件

@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]!\"
)

You don't need to repeat the file name in move command. 您无需在move命令中重复文件名。

For a further description of array management in Batch files, see: Arrays, linked lists and other data structures in cmd.exe (batch) script 有关批处理文件中阵列管理的进一步说明,请参阅: cmd.exe(批处理)脚本中的阵列,链接列表和其他数据结构

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 根据名称批量移动文件到新的子文件夹 - Batch move files to new subfolders based on name windows bat script find替换文件夹和子文件夹中的每个文件 - windows bat script find replace every file in folder and subfolders 创建Bat文件以对文件夹和子文件夹中的所有文件执行命令 - Creating Bat file to execute a command on all files in folder and subfolders Bat脚本可查找和替换多个子文件夹中的文件-将.java文件替换为特定文件夹中的.class文件 - Bat script to find and replace files in multiple subfolders - replace .java files with .class files from specific folder .bat 文件通过文件扩展名和 ZE83AED3DDF4667DEC0DAAAACB2BB3BE0BZ 文件名移动文件 - .Bat file to move file by file extension and substring file name 如何从bat脚本变量中找到的父文件夹中删除子文件夹和文件? - How to delete subfolders and files from parent folders found in the variable of a bat script? 使用.bat文件将当前文件夹中的所有文件和所有子文件夹合并到一个文件中 - Merge all files from the current folder and all subfolders in one file using .bat file 通过BAT脚本将生成的dll文件移动到特定文件夹? - Move built dll file to specific folder by BAT script? Windows .BAT-移动文件 - Windows .BAT - Move File 使用bat文件根据文件名中的日期查找和移动文件 - Find and move files based on a date in the filename using bat file
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM