繁体   English   中英

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

[英]How to move files from a source directory to a destination directory with name of first part of file name?

在其他人的帮助下编写了下面的批处理文件,但我没有太多经验,所以这对我来说有点困难。

我正在尝试将 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

试试这个批处理文件代码:

@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在指定目录中搜​​索

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

如果指定的目录根本不存在或没有与该模式匹配的文件,则DIR输出的用于处理STDERR的错误消息通过使用2>nul重定向到设备NUL来抑制。

阅读有关使用命令重定向运算符的 Microsoft 文档以了解2>nul的说明。 重定向运算符>必须在FOR命令行上使用脱字符^进行转义,以便在 Windows 命令解释器在执行命令FOR之前处理此命令行时解释为文字字符,该命令使用在后台启动的单独命令进程执行嵌入式dir命令行。

FOR捕获写入已启动命令进程的STDOUT的所有内容,并逐行处理捕获的输出。

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

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

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

因此,第一个FOR分配给A例如RANSOM-NH_2018-08-07_5485A635.pdf和第二个FOR处理RANSOM-NH_2018-08-07_5485A635并将字符串分配给B RANSOM-NH

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

该文件从源目录移动到目标目录中的现有子目录,并覆盖文件目标目录中具有相同名称的现有文件。

如果没有以下划线开头的 PDF 文件或在日期部分之前有多个下划线的 PDF 文件,则可以优化第二个FOR循环。

@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*导致根据ASCII 表将文件名的第一个下划线分隔部分分配给循环变量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 /?
  • set /?
  • setlocal /?

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM