根据文件名的一部分批量创建文件夹并将文件移动到该文件夹中

4

我有1.6百万(!)个PDF文件存放在一个文件夹中。这些文件的命名方式都类似于这样:

LAST_FIRST_7-24-1936 Diagnostic - Topography 11-18-10_1.pdf
LAST_FIRST_7-24-1936 Glasses RX 6-1-11_3.pdf

我需要根据文件名的第一部分创建一个文件夹,然后将该文件和所有具有相同文件名第一部分的其他文件移动到该文件夹中。在这种情况下,文件夹将被命名为“LAST_FIRST_7-24-1936”。文件夹的名称始终与文件名的第一部分相同,直到空格。

我想创建一个批处理文件来完成这个任务。根据我粗略的编程知识,我想出了以下逻辑过程:

1 Take the first file and name it var1
2 Remove everything after the space in var1 and name it var2
3 Create a folder named var2
4 Move the file var1 into the folder var2
5 If there are more files Go to line 1, otherwise end

我不知道这个的正确语法应该是什么。

我找到了这个链接Need a script to create folders based on file names, and auto move files,我根据那个链接制作了这个批处理文件。

pushd D:\Data\Medinfo PDFs
for %%F in (*.pdf) do (
  2>nul md "%%~nF"
  >nul move /y "%%~nF*.*" "%%~nF"
)
popd

但是,它不允许我仅使用文件名的一部分来创建文件夹名称。如果我能解决这个问题,我认为它会起作用。 我知道我需要为文件夹名称创建变量,但我不知道如何编辑文件名变量以删除空格后面的所有内容。 任何帮助都将不胜感激。只要它在 Windows Server 2008 R2 中本地工作即可,我不反对在 PowerShell 或其他东西中完成此操作。

2个回答

5
@ECHO OFF
SETLOCAL
SET "sourcedir=c:\sourcedir"
PUSHD %sourcedir%
FOR /f "tokens=1*" %%a IN (
 'dir /b /a-d "*_*_*-*-* *.*"'
 ) DO (  
 ECHO MD %%a
 ECHO MOVE "%%a %%b" .\%%a\
)
POPD
GOTO :EOF

这应该可以完成所需任务,或者至少显示所需的指令。

如果您对发出的命令满意,请将sourcedir设置为所需的根目录,并删除两个echo关键字以激活。

MD尝试重新创建现有目录时生成的“目录已经存在”消息可以通过在MD行末尾添加2>nul来抑制。

同样,附加>nulMOVE行末尾可以抑制一个文件已移动的报告。

2>nul抑制错误消息(尝试创建现有目录是一种错误),而“文件已移动”消息是普通输出消息,因此存在差异。


补充说明 - 工作原理。

首先,PUSHD将当前目录设置为目标目录。
FOR/FDIR命令输出分词。 tokens=1*子句指示将第一个标记(1)分配给指定的元变量(%%a),并隐式地将第二个标记(*)分配给%%b - 简单地按字母顺序排列下一个。标记*表示显式提到这些标记号之后的所有内容。没有使用delims子句,因此使用默认分隔符(SEPARATORS集合 SPACE , ; TAB)。

DIR针对*_*_*-* *.*掩码进行定位,因此仅会定位与该掩码匹配的文件 - 其中*表示任意数量的任何字符。由于掩码被"引用",因此空格包括在掩码中。如果没有引号,则将指定两个单独的掩码。 /b选项以基本形式生成列表,即仅名称,无标题或摘要。 /a-d选项抑制了可能适合掩码的任何目录名称。

因此,对于LAST_FIRST_7-24-1936 Diagnostic - Topography 11-18-10_1.pdfdir列出LAST_FIRST_7-24-1936 Diagnostic - Topography 11-18-10_1.pdf并使用SPACE作为分隔符,FOR/F将其分词为LAST_FIRST_7-24-1936Diagnostic - Topography 11-18-10_1.pdf,分别赋值给%%a%%b

文件名可以通过在%%a%%b之间重新插入空格来重构。任何包含分隔符的文件名都需要用引号括起来,以将字符分组并表示它们不是分离的元素。移动目标以\结尾,以指定“这是一个目录名称”。POPD将恢复原始登录目录。

这个代码可以运行,但我想了解它是如何工作的。如果我单独运行DIR命令,我会得到完整的文件名,而不是新文件夹的名称。我对%%b变量感到困惑。它从哪里来?你的代码似乎将DIR命令的结果分成了两个变量%%a和%%b,但我不明白是什么或者怎么做到的。 如果你没有时间解释,我理解,并且非常感谢你的帮助! - JakOwnin

0

这确实帮了我很大的忙,我对它进行了轻微修改以处理我的数码照片(我是一名摄影师),并将批处理文件命名为FolderAndMove。这是我的代码:

@ECHO OFF
SETLOCAL
SET "sourcedir=***PASTE_DIRECTORY_HERE***"
PUSHD %sourcedir%
FOR /f "tokens=1,2,3,4 delims=_" %%a IN (
 'dir /b /a-d "*_*_*_*.*"'
 ) DO (  
 MD %%a_%%b 2>nul
 MOVE "%%a_%%b_%%c_%%d" .\%%a_%%b\ >nul
)
POPD
GOTO :EOF

这是我为其他摄影师制作的简单说明:

FolderAndMove将获取一个文件夹,其中包含格式为*_*_*_*.*(例如LastName_FirstInitial_Event#_Sequence#.JPG)的文件,为每个唯一的*_*文件前缀(在示例中为LastName_FirstInitial)在所选根文件夹内创建一个单独的文件夹,并将遵循*_*_*_*.*约定的所有文件移动到与其前缀对应的*_*文件夹中。

请注意,文件格式是精确的:变量(*)必须由下划线分隔(分段),没有空格,以便FolderAndMove正常工作。


2
我的文件名为Xyz.txt。我该如何为它提供令牌? - ben

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接