如何将文件名开头部分的文件从源目录移动到目标目录? [英] How to move files from a source directory to a destination directory with name of first part of file name?

查看:114
本文介绍了如何将文件名开头部分的文件从源目录移动到目标目录?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经在他人的帮助下编写了以下批处理文件,但是我没有太多的经验,因此对我来说有点困难.

I have written the batch file below with the help of others, but I don't have much experience and so this is a bit difficult for me.

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

I'm trying to transfer PDF files from a specific location to individual folders in another location. Each file name is in this format RANSOM-NH_2018-08-07_5485A635.pdf and based on RANSOM-NH_ the batch file should transfer/move the PDF file to it's proper folder named as such RANSOM-NH_Ransom INC. So based on the initial part of the file name, the file should be moved to folder of which name begins with first part of file name.

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

Some examples of file and folder names:

文件名:

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_移到了它根本不应该使用的同一文件夹中.

The problem I have is that the script written still moves the file RANSOM-NH8_ in the same folder which it shouldn't do at all.

@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

推荐答案

尝试此批处理文件代码:

Try this batch file code:

@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在后台的命令行开始:

The first FOR executes in a separate command process started with cmd.exe /C in background the command line:

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

DIR 在指定目录中搜​​索

DIR searches in specified directory for

  • 由于/A-D-H只是非隐藏文件(属性不是目录,也不是隐藏的)
  • 与通配符模式*_????-??-??_*.pdf匹配,该通配符模式也可能只是*_*.pdf
  • 并输出以纯格式处理 STDOUT ,因为/B只是带有文件扩展名的文件名,而没有文件路径.
  • just non-hidden files because of /A-D-H (attribute not directory and not hidden)
  • matching the wildcard pattern *_????-??-??_*.pdf which could be also just *_*.pdf
  • and outputs to handle STDOUT in bare format because of /B just the file names with file extension, but without file path.

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

The error message output by DIR to handle STDERR if the specified directory does not exist at all or there is no file matching the pattern is suppressed by redirecting it with 2>nul to device NUL.

阅读有关使用命令重定向运算符以获取2>nul的解释.当Windows命令解释器在执行命令 FOR 之前处理此命令行时,重定向操作符>必须在 FOR 命令行上转义字符^进行转义,以将其解释为文字字符. >,它将在后台启动的单独命令过程中执行嵌入的dir命令行.

Read the Microsoft documentation about Using Command Redirection Operators for an explanation of 2>nul. The redirection operator > must be escaped with caret character ^ on FOR command line to be interpreted as literal character when Windows command interpreter processes this command line before executing command FOR which executes the embedded dir command line in a separate command process started in background.

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

FOR captures everything written to STDOUT of started command process and processes the captured output line by line.

FOR 默认情况下会忽略所有空行(此处不出现)和所有以分号开头的行.文件名可以以分号开头.因此,使用选项eol=|将行尾字符重新定义为文件名不能包含的竖线,请参阅Microsoft文档页

FOR ignores by default all empty lines (do not occur here) and all lines starting with a semicolon. A file name could begin with a semicolon. For that reason option eol=| is used to redefine end of line character to vertical bar which a file name can't contain, see Microsoft documentation page Naming Files, Paths, and Namespaces.

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

FOR would split up also each line into substrings (tokens) using space/tab as delimiters and would assign just the first space/tab separated string to specified loop variable A. This splitting behavior is not wanted here as file names can contain one or more space characters. Therefore the option delims= is used to define an empty list of delimiters which disables line splitting completely and results in assigning entire file name with extension to loop variable A.

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

The second FOR processes just the file name (without extension) as string. This time the file name is split up using the underscore as delimiter because of delims=_ with assigning just first underscore delimited string to loop variable B because of tokens=1. Well, tokens=1 is the default on using for /F and so this option string could be removed from code.

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

So the first FOR assigns to A for example RANSOM-NH_2018-08-07_5485A635.pdf and the second FOR processes RANSOM-NH_2018-08-07_5485A635 and assigns to B the string RANSOM-NH.

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

The third FOR with option /D searches for non-hidden directories in destination directory starting with string assigned to loop variable B and an underscore. If such a directory is found, its name with full path is assigned to loop variable C and executes the command MOVE.

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

The file is moved from source to existing subdirectory in destination directory with overwriting an existing file with same name in target directory of the file.

当从来没有下划线开头的PDF文件或在日期部分之前有多个下划线的PDF文件时,可以优化第二个 FOR 循环.

The second FOR loop could be optimized away when there are never PDF files starting with an underscore or which have more than one underscore before the date part.

@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. com/"rel =" nofollow noreferrer> ASCII表,而不必在下划线上进行进一步的划分.

Option tokens=1* results in assigning first underscore delimited part of file name to loop variable A and rest of file name to next loop variable B according to ASCII table without further splitting up on underscores.

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

But please take into account that the optimized version does not work for file names like

  • _RANSOM-X_2018-08-07_5485A635.pdf ...下划线开头,或
  • RANSOM-Y__2018-08-07_5485A635.pdf ...迄今为止还有多个下划线.
  • _RANSOM-X_2018-08-07_5485A635.pdf ... underscore at beginning, or
  • RANSOM-Y__2018-08-07_5485A635.pdf ... more than one underscore left to date part.

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

The optimized version can be further optimized to a single command line:

@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\"

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

Well, the not optimized version could be also written as even longer single command line:

@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\"

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

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

  • dir /?
  • echo /?
  • endlocal /?
  • for /?
  • move /?
  • set /?
  • setlocal /?
  • dir /?
  • echo /?
  • endlocal /?
  • for /?
  • move /?
  • set /?
  • setlocal /?

这篇关于如何将文件名开头部分的文件从源目录移动到目标目录?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆