如何使用文件名的第一部分的名称将文件从源目录移动到目标目录?

时间:2018-09-12 01:40:15

标签: batch-file cmd batch-processing

我已经用help of others在下面编写了批处理文件,但是我没有太多经验,所以这对我来说有点困难。

我正在尝试将PDF文件从特定位置传输到另一个位置的单个文件夹。每个文件名都采用RANSOM-NH_2018-08-07_5485A635.pdf格式,并且基于RANSOM-NH_的批处理文件应将PDF文件传输/移动到名为RANSOM-NH_Ransom INC的适当文件夹中。因此,应根据文件名的开头部分将文件移至其名称以文件名的第一部分开头的文件夹。

文件和文件夹名称的一些示例:

文件名:

RANSOM-NH_2018-06-20_2018_5849.pdf
GREENWOOD_2018-07-02_66902.pdf
GLSCIENCES_2018-07-24_24811.pdf
CPI_2018-08-01_20039035.pdf
ALDR_2018-08-08_545477636.pdf
ACCQTRAX_2018-07-26_173845.pdf

文件夹名称:

RANSOM-NH_Ransom INC
GREENWOOD_Greenwood Products, Inc
GLSCIENCES_GL Sciences, Inc
CPI_CPI International
ALDR_Sigma-Aldrich, Inc
ACCQTRAX_AccQtrax

我的问题是编写的脚本仍将文件RANSOM-NH8_移动到根本不应该在同一文件夹中的文件。

@ECHO OFF
SETLOCAL
SET "sourcedir=C:\Users\Alpha\Documents\NOTEPAD Coding\File Transfer Coding\Files"
SET "destdir=C:\Users\Alpha\Documents\NOTEPAD Coding\File Transfer Coding\Transfer"
FOR /f "delims=" %%a IN ('dir /b /a-d "%sourcedir%\*.pdf" ') DO (
    FOR /f "tokens=1 delims=_-" %%b IN ("%%a") DO (
        FOR /f "delims=" %%d IN ('dir /b /ad "%destdir%\*%%b*" ') DO (
            MOVE "%sourcedir%\%%a" "%destdir%\%%d\"
        )
    )
)
GOTO :EOF

1 个答案:

答案 0 :(得分:0)

尝试此批处理文件代码:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "SourceDir=%UserProfile%\Documents\NOTEPAD Coding\File Transfer Coding\Files"
set "DestDir=%UserProfile%\Documents\NOTEPAD Coding\File Transfer Coding\Transfer"

for /F "eol=| delims=" %%A in ('dir /B /A-D-H "%SourceDir%\*_????-??-??_*.pdf" 2^>nul') do (
    for /F "eol=| tokens=1 delims=_" %%B in ("%%~nA") do (
        for /D %%C in ("%DestDir%\%%B_*") do move /Y "%SourceDir%\%%A" "%%C\"
    )
)

endlocal

第一个 FOR 在以cmd.exe /C开头的单独命令过程中在后台命令行中执行:

dir /B /A-D-H "C:\Users\Alpha\Documents\NOTEPAD Coding\File Transfer Coding\Files\*_????-??-??_*.pdf" 2>nul

DIR 在指定目录中搜​​索

  • 由于/A-D-H只是非隐藏文件(属性不是目录,也不是隐藏的)
  • 匹配通配符模式*_????-??-??_*.pdf,也可能只是*_*.pdf
  • 并输出以裸格式处理 STDOUT ,因为/B只是带有文件扩展名的文件名,而没有文件路径。

DIR 输出的用于处理 STDERR 的错误消息,如果指定的目录根本不存在或不存在与模式匹配的文件,可以使用{ {1}}到设备 NUL

也请阅读有关Using Command Redirection Operators的Microsoft文章,以获取2>nul的解释。当Windows命令解释器在执行命令之前处理此命令行时,重定向操作符2>nul必须在 FOR 命令行上使用脱字符号>进行转义,才能被解释为文字字符。 FOR ,它将在后台启动的单独命令进程中执行嵌入式^命令行。

FOR 捕获开始命令过程写入 STDOUT 的所有内容,并逐行处理捕获的输出。

FOR 默认情况下忽略所有空行(此处不出现)和所有以分号开头的行。文件名可以以分号开头。因此,使用选项dir将行尾字符重新定义为文件名不能包含的竖线,请参阅Microsoft关于Naming Files, Paths, and Namespaces的文章。

FOR 还将使用空格/制表符作为分隔符将每一行拆分为子字符串(令牌),并且仅将第一个空格/制表符分隔的字符串分配给指定的循环变量eol=|。由于文件名可以包含一个或多个空格字符,因此此处不需要这种拆分行为。因此,选项A用于定义一个空的定界符列表,该列表将完全禁用行分割,并导致将整个文件名的扩展名分配给循环变量delims=

第二个 FOR 仅将文件名(不带扩展名)处理为字符串。这次由于A使用下划线作为分隔符来分割文件名,因为delims=_仅将第一个下划线分隔的字符串分配给循环变量B。好吧,tokens=1是使用tokens=1时的默认设置,因此可以从代码中删除此选项字符串。

因此第一个 FOR 分配给for /F,例如A,第二个 FOR 处理RANSOM-NH_2018-08-07_5485A635.pdf并分配给{{ 1}}字符串RANSOM-NH_2018-08-07_5485A635

带有选项B的第三个 FOR 会在目标目录中搜索未隐藏的目录,该目录以分配给循环变量RANSOM-NH的字符串和下划线开头。如果找到了这样的目录,则将其具有完整路径的名称分配给循环变量/D并执行命令 MOVE

通过覆盖文件目标目录中同名的现有文件,文件从源移动到目标目录中的现有子目录。

第二个 FOR 循环可以被优化,因为从不存在以下划线开头或日期部分之前有多个下划线的PDF文件。

B

选项C导致根据ASCII table将文件名的第一个下划线定界部分分配给循环变量@echo off setlocal EnableExtensions DisableDelayedExpansion set "SourceDir=%UserProfile%\Documents\NOTEPAD Coding\File Transfer Coding\Files" set "DestDir=%UserProfile%\Documents\NOTEPAD Coding\File Transfer Coding\Transfer" for /F "eol=| tokens=1* delims=_" %%A in ('dir /B /A-D-H "%SourceDir%\*_????-??-??_*.pdf" 2^>nul') do ( for /D %%C in ("%DestDir%\%%A_*") do move /Y "%SourceDir%\%%A_%%B" "%%C\" ) endlocal ,并将文件名的其余部分分配给下一个循环变量tokens=1*下划线。

但是请考虑到优化版本不适用于类似文件名的

  • A ...下划线开头,或
  • B ...迄今剩余的下划线超过一个。

优化后的版本可以进一步优化为单个命令行:

_RANSOM-X_2018-08-07_5485A635.pdf

嗯,未经优化的版本也可以写成更长的单个命令行:

RANSOM-Y__2018-08-07_5485A635.pdf

要了解所使用的命令及其工作方式,请打开命令提示符窗口,在其中执行以下命令,并非常仔细地阅读每个命令显示的所有帮助页面。

  • @for /F "eol=| tokens=1* delims=_" %%A in ('dir /B /A-D-H "%UserProfile%\Documents\NOTEPAD Coding\File Transfer Coding\Files\*_????-??-??_*.pdf" 2^>nul') do @for /D %%C in ("%UserProfile%\Documents\NOTEPAD Coding\File Transfer Coding\Transfer\%%A_*") do @move /Y "%UserProfile%\Documents\NOTEPAD Coding\File Transfer Coding\Files\%%A_%%B" "%%C\"
  • @for /F "eol=| delims=" %%A in ('dir /B /A-D-H "%UserProfile%\Documents\NOTEPAD Coding\File Transfer Coding\Files\*_????-??-??_*.pdf" 2^>nul') do @for /F "eol=| tokens=1 delims=_" %%B in ("%%~nA") do @for /D %%C in ("%UserProfile%\Documents\NOTEPAD Coding\File Transfer Coding\Transfer\%%B_*") do @move /Y "%UserProfile%\Documents\NOTEPAD Coding\File Transfer Coding\Files\%%A" "%%C\"
  • dir /?
  • echo /?
  • endlocal /?
  • for /?
  • move /?