【问题标题】:Batch: Using lookup file to search directory tree and move files批处理:使用查找文件搜索目录树和移动文件
【发布时间】:2017-04-21 09:42:44
【问题描述】:

我的查询解决了包含一系列复杂子目录的大型图像目录,并且需要执行文件列表查找并移动所述文件。

我在 StackOverflow 和其他支持论坛上找到了一些可能的解决方案来解决我的请求,这是我目前的解决方案:

@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

这工作得很好,但只针对父目录。如何让这个批处理脚本从父目录自上而下搜索并找到查找列表中提供的所有匹配文件?

【问题讨论】:

  • for /F "delims=" %%a in ('type "%FileList%"') do for /F "delims=" %%b in ('dir /B /S /A:-D "%Source%\%%a"') do move "%%b" "%Target%"

标签: batch-file move


【解决方案1】:

这是您的代码的改进版本,包括递归搜索源目录的解决方案。为此,我假设 目标目录是平面的,因此不会从源目录复制子目录。所以这里是代码:

@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

除了一些小的语法改进之外,主要的变化是额外的嵌套for /F %%b 循环,它解析dir 命令的输出,该命令依次搜索%%a 给出的每个文件名,也在子-源目录的目录。


如果你想将源目录中的各个子目录复制到目标目录中,那么目标目录是递归的,则需要修改脚本:

@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

这就是我所做的:

  • 添加了行for /D %%d in ("%Source%") do set "Source=%%~fd",除了从给定的路径获取到源目录的完整绝对路径和解析路径外,什么都不做;这是必要的,因为在路径上进行了一些字符串操作(例如,C:\USERS\.\directory 等同于作为路径的C:\Users\any\..\Directory,尽管它们是不同的字符串;for /D 命令行将此类路径解析为C:\users\directory);
  • for /F %%b循环内部,%%b存储在变量Item中,构成完整路径; Parent存储父目录的完整路径,并附加\.;例如,如果当前项目是C:\users\directory\subdir\file.ext,则Parent 持有C:\users\directory\subdir\.
  • delayed variable expansion 已启用,因为变量 ItemParent 被设置在同一代码块中读取;它通常不启用但在循环中切换,以免在路径中出现感叹号时造成任何麻烦;
  • set "Parent=!Parent:*%Source%=!" 行从Parent 中存储的路径中删除了源目录;例如,当源目录为C:\users\directory时,Parent路径C:\users\directory\subdir\.变为.\subdir\.,因此Parent变为相对路径;
  • 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

请注意,源目录不得包含任何 != 字符,脚本才能正常工作!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-21
    • 2010-09-19
    • 1970-01-01
    相关资源
    最近更新 更多