我使用的是Windows 7。
我有数百个文件需要移动到各自的文件夹中。这是一个示例文件名:
文件名:" SMITH John登录表"
遗憾的是,这些文件夹仅以其最后名称和名字命名。例如:
文件夹名称:SMITH John已完成。
我已经创建了一个批处理脚本(感谢其他Q& As),如果文件夹名称为" LAST Name和First name"但是,如果文件夹名称在名字后面有额外的单词,则需要帮助。任何建议都会很棒。
答案 0 :(得分:0)
您可以使用for循环提取字符串的特定部分:
@echo off
setlocal EnableDelayedExpansion
for /f "tokens=1,2 delims= " %%a in ("!placefilenameshere!") do (
set lastname=%%a
set firstname=%%b
)
使用另一个for循环,您可以自己完成(子)目录:
set parentdir="C:\foo\bar"
REM you can use network paths as well!
pushd !parentdir!
for /r %%g in (.) do (
set dirname=%%g
set dirsave=%%g
for /L %%I in (1,1,20) do set dirname=!dirname:*\=!
for /f "tokens=1,2 delims= " %%m in ("!dirname!") do (
set lastdir=%%m
set firstdir=%%n
)
if /i "x!lastdir! !firstdir!"=="x!lastname! !firstname!" (
popd
REM MOVE FILES TO DIRSAVE
pushd !parentdir!
)
)
说明:
使用第一个块从文件名中提取前两个单词,您可以将循环的第一个括号放在变量中,例如。
因此,last-和firstname保存在两个变量lastname
和firstname
中
将变量parentdir
更改为您要放置文件的所有文件夹所在的路径。
第二个循环遍历上面指定的目录中的文件夹,并将目录路径保存在两个变量中。一个用于稍后datsave
,一个用于检查是否找到了正确的目录datname
。
那里的小循环从路径变量中删除所有父目录字符串,然后从中获取前两个单词。
实施例:
C:\some\long\path\goes here
首先缩短为goes here
,然后分为lastdir = goes
和firstdir = here
。
最后一步是检查目录中的前两个单词和文件名是否相同(不区分大小写)。在那里你可以放置命令将文件移动到路径dirsave
,这是保存的完整路径(见上文)。
将所有内容放入另一个遍历文件名的循环中,它应该可以正常工作。
然而,这是未经测试的......有些经验丰富的人可能希望在出现问题之前首先考察一下......
答案 1 :(得分:0)
@ECHO Off
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET "destdir=U:\destdir"
FOR /f "delims=" %%a IN (
'dir /b /a-d "%sourcedir%\*" '
) DO (
SET "destsubdir="
CALL :finddest %%a
IF DEFINED destsubdir (CALL :transfer "%%a"
) ELSE (
ECHO %%a: No unique subdir found
)
)
GOTO :EOF
:transfer
ECHO(MOVE "%sourcedir%\%~1" "%destdir%\%destsubdir%\"
GOTO :eof
:finddest
:: get the next subdir part
SET "subdirfound=%1"
:: If there are no more, exit - unique not found
IF NOT DEFINED subdirfound GOTO nouniquefound
:: see whether there is exactly one destination subdir with
:: the accumulated subdirname so far
IF DEFINED destsubdir (
SET "accumsubdir=%destsubdir% %1"
) ELSE (
REM force at least 2 names
SET "destsubdir=%1"&shift&GOTO finddest
)
shift
SET "subdirfound="
FOR /f "delims=" %%d IN ('dir /b/ad "%destdir%\%accumsubdir%*" 2^>nul') DO (
rem if subdirfound is already set, 2 or more exist
IF DEFINED subdirfound SET "destsubdir=%accumsubdir%"&GOTO finddest
rem otherwise, record destination subdirectory to use
SET "subdirfound=%%d"
)
:: none are found or unique has been found - now in subdirfound
:nouniquefound
SET "destsubdir=%subdirfound%"
IF NOT DEFINED destsubdir GOTO :EOF
GOTO :eof
您需要更改sourcedir
和destdir
的设置以适合您的具体情况。
假设源目录是:
Volume in drive U has no label.
Volume Serial Number is BDA0-0000
Directory of u:\sourcedir
19/09/2016 23:06 0 q1234
19/09/2016 23:06 0 Smith John Sign on sheet
19/09/2016 23:06 0 Robinson Bill Sign on sheet
19/09/2016 23:06 0 Robinson Bill expenses
19/09/2016 23:06 0 Robinson George expenses
19/09/2016 23:06 0 Robinson Fred expenses
19/09/2016 23:06 0 Jones George expenses
19/09/2016 23:06 0 von Richthofen Manfred expenses
19/09/2016 23:06 0 von Richthofen Manfred timesheet
9 File(s) 0 bytes
目标目录是
Volume in drive U has no label.
Volume Serial Number is BDA0-0000
Directory of u:\destdir
19/09/2016 23:06 <DIR> .
19/09/2016 23:06 <DIR> ..
19/09/2016 23:06 <DIR> Smith John data
19/09/2016 23:06 <DIR> Robinson Bill data
19/09/2016 23:06 <DIR> Jones George data
19/09/2016 23:06 <DIR> von Richthofen Manfred data
19/09/2016 23:06 <DIR> von Richthofen Lothar data
19/09/2016 23:06 <DIR> q1234
0 File(s) 0 bytes
然后运行此批处理产生
q1234: No unique subdir found
MOVE "U:\sourcedir\Smith John Sign on sheet" "U:\destdir\Smith John data\"
MOVE "U:\sourcedir\Robinson Bill Sign on sheet" "U:\destdir\Robinson Bill data\"
MOVE "U:\sourcedir\Robinson Bill expenses" "U:\destdir\Robinson Bill data\"
Robinson George expenses: No unique subdir found
Robinson Fred expenses: No unique subdir found
MOVE "U:\sourcedir\Jones George expenses" "U:\destdir\Jones George data\"
MOVE "U:\sourcedir\von Richthofen Manfred expenses" "U:\destdir\von Richthofen Manfred data\"
MOVE "U:\sourcedir\von Richthofen Manfred timesheet" "U:\destdir\von Richthofen Manfred data\"
使用for
的{{1}}循环将每个文件名依次分配给%%a
,初始化%%a
并使用文件名作为参数执行destsubdir
。
:finddest
会将目标目录名分配给:finddest
,或者会在destsubdir
清除后返回,表示错误。 destsubdir
检测到差异,并运行if defined
移动文件(目前只是:transfer
建议的echo
)或报告它无法找到唯一的子目录名称。
move
会将名字设置为:finddest
和destsubdir
,以便下一个名称为shift
如果我们的名字用完了,我们还没找到一个唯一的子目录名称,所以我们退出%1
为空。这是destsubdir
的情况,因为没有第二个名字。
然后,我们将下一个名称附加到q1234
以形成destsubdir
和accumsubdir
,以删除刚使用的名称。
然后将shift
设置为 nothing ,为下一步做好准备。
与累积子目录匹配的每个目录名都分配给subdirfound
。如果已设置%%d
,则会有2个或更多匹配的名称,因此返回subdirfound
以累积下一个名称等。
如果finddest
循环完成,则找到一个目标子目录名称(for
包含其名称)或者没有(subdirfound
仍然为空)。无论哪种方式,我们都可以将subdirfound
分配给该值,然后退出子例程。
因此,文件将使用3个名称传输到例如destsubdir
,因为von Richthofen Manfred
不是唯一的。例如,这可以用来区分约翰·A·史密斯和约翰·B·史密斯,或者范德瓦尔斯·约翰内斯和范德瓦尔斯·雅各布斯之间。