批处理:使用查找文件搜索目录树并移动文件 [英] Batch: Using lookup file to search directory tree and move files
问题描述
我的查询围绕一个大目录的图像进行解析,该目录包含一系列复杂的子目录,并且需要对文件列表进行查找,然后移动所述文件.
My query resolves around a large directory of images, with a complex series of sub-directories, and needing to perform a lookup for a list of files, and moving said files.
我在StackOverflow和其他支持论坛上找到了一些可能的解决方案,这是我当前的解决方案:
I have found a few possible solutions to my request on StackOverflow and other support forums and here is my current solution:
@echo off
set Source=C:\users\directory
set Target=C:\users\target
set FileList=C:\users\lookup\list.txt
echo.
if not exist "%Source%" echo Source folder "%Source%" not found & goto Exit
if not exist "%FileList%" echo File list "%FileList%" not found & goto Exit
if not exist "%Target%" md "%Target%"
for /F "delims=" %%a in ('type "%FileList%"') do move "%Source%\%%a" "%Target%"
:Exit
echo.
echo press the Space Bar to close this window.
pause > nul
这工作得很好,但仅针对父目录.如何从父目录的顶部向下搜索此批处理脚本,并查找查找列表中提供的所有匹配文件?
This works perfectly fine but only targets the parent directory. How can I have this Batch script search top down from the parent directory and find all matching files provided in the lookup list?
推荐答案
此处是代码的改进版本,包括递归搜索源目录的解决方案.为此,我假设目标目录是平坦的,因此不会从源目录复制任何子目录.所以这是代码:
Here is an improved version of your code including the solution to search the source directory recursively. For this I assumed that the target directory is flat, so no sub-directories are to be copied from the source directory. So here is the code:
@echo off
set "Source=C:\users\directory"
set "Target=C:\users\target"
set "FileList=C:\users\lookup\list.txt"
echo/
if not exist "%Source%" echo Source folder "%Source%" not found & goto :Quit
if not exist "%FileList%" echo File list "%FileList%" not found & goto :Quit
2> nul md "%Target%"
for /F usebackq^ delims^=^ eol^= %%a in ("%FileList%") do (
for /F "delims=" %%b in ('dir /B /S /A:-D "%Source%\%%a"') do (
move "%%b" "%Target%"
)
)
:Quit
echo/
echo Press the Space bar to close this window.
pause > nul
除了语法上的一些小改进之外,主要的变化是/F %% b 的附加嵌套循环,该循环解析
dir
命令的输出,该命令依次在源目录的子目录中搜索 %% a
给出的每个文件名.
Besides some minor syntax improvements, the major change is the additional nested for /F %%b
loop, which parses the output of a dir
command, which in turn searches for each file name given by %%a
also in the sub-directories of the source directory.
如果要将源目录中的各个子目录复制到目标目录,以便目标目录是递归的,则需要对脚本进行调整:
In case you want the respective sub-directories in the source directory to be copied to the target directory, so the target directory is recursive, the script needs to be adapted:
@echo off
set "Source=C:\users\directory"
set "Target=C:\users\target"
set "FileList=C:\users\lookup\list.txt"
echo/
if not exist "%Source%" echo Source folder "%Source%" not found & goto :Quit
if not exist "%FileList%" echo File list "%FileList%" not found & goto :Quit
for /D %%d in ("%Source%") do set "Source=%%~fd"
2> nul md "%Target%"
for /F usebackq^ delims^=^ eol^= %%a in ("%FileList%") do (
for /F "delims=" %%b in ('dir /B /S /A:-D "%Source%\%%a"') do (
set "Item=%%b"
set "Parent=%%~dpb."
setlocal EnableDelayedExpansion
set "Parent=!Parent:*%Source%=.!"
2> nul md "!Target!\!Parent!"
move "!Item!" "!Target!\!Parent!"
endlocal
)
)
:Quit
echo/
echo Press the Space bar to close this window.
pause > nul
这就是我所做的:
- 在(%Source%")中为/D %% d添加了行
确实设置了"Source = %%〜fd"
,除了获得完整的绝对路径和解析路径之外,它什么都没有给定目录中的源目录;这是必要的,因为在路径上进行了一些字符串操作(例如,C:\ USERS \ .. \ directory
等效于C:\ Users \ any \ .. \ Directory 代码>作为路径,尽管它们是不同的字符串;/D
命令行的会将此类路径解析为
C:\ users \ directory
); 在/F %% b 循环的 - 内,
%% b
存储在变量Item
中,该变量构成完整路径;Parent
存储到父目录的完整路径,并附加\.
;例如,如果当前项是C:\ users \ directory \ subdir \ file.ext
,则Parent
保留C:\ users \ directory \ subdir \.
; - 延迟变量扩展已启用,因为变量
Item
和Parent
设置为和在同一代码块中读取;通常不会启用它,而是在循环中进行切换,以便在路径中出现感叹号时不会造成任何麻烦; - 行
set"Parent =!Parent:*%Source%=!"
从存储在Parent
中的路径中删除源目录;例如,当源目录为时,
,因此Parent
路径C:\ users \ directory \ subdir \.
变为.\ subdir \.
.> C:\ users \ directoryParent
成为相对的; -
2>nul md!Target!\!Parent!"
确保目标目录中存在Parent
目录(2> nul
禁止显示潜在的错误消息); 终于,运动完成了;例如,当当前项目为
C:\ users \ directory \ subdir \ file.ext
,而目标目录为 C:\ users \ target
时,将其移至目录 C:\ users \ target \.\ subdir \.
,等效于 C:\ users \ target \ subdir
; - added line
for /D %%d in ("%Source%") do set "Source=%%~fd"
, which does nothing but get the full absolute and resolved path to the source directory from the given one; this is necessary because there are some string manipulations done on paths (for instance,C:\USERS\.\directory
is equivalent toC:\Users\any\..\Directory
as a path, although they are different strings; thefor /D
command line resolves such paths toC:\users\directory
); - inside of the
for /F %%b
loop,%%b
is stored in variableItem
, which constitutes a full path;Parent
stores the full path to the parent directory with\.
appended; for example, if the current item isC:\users\directory\subdir\file.ext
,Parent
holdsC:\users\directory\subdir\.
; - delayed variable expansion is enabled, because the variables
Item
andParent
are set and read within the same block of code; it is not generally enabled but toggled in the loop in order not to cause any trouble when exclamation marks occur in the paths; - the line
set "Parent=!Parent:*%Source%=!"
removes the source directory trom the path stored inParent
; for example, theParent
pathC:\users\directory\subdir\.
becomes.\subdir\.
when the source directory isC:\users\directory
, so theParent
becomes relative; 2> nul md "!Target!\!Parent!"
ensures that theParent
directory exists in the target directory (2> nul
suppresses a potential error message);- finally, the movement is done; for example, when the current item is
C:\users\directory\subdir\file.ext
and the target directory isC:\users\target
, it is moved into the directoryC:\users\target\.\subdir\.
, which is equivalent toC:\users\target\subdir
;
请注意,源目录不得包含任何!
和 =
字符,脚本才能正常工作!
Note that the source directory must not contain any !
and =
characters for the script to work!
这篇关于批处理:使用查找文件搜索目录树并移动文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!