我想为以下场景创建一个批处理文件/windows命令:
我在具有特定文件名模式的文件夹中有一个文件列表,例如...XXXX_XX其中X主要是一个数字。 这里的主要问题是此模式的位置实际上不是固定的,并且可能发生在文件名中的任何位置。
例如:
这些是文件名:
1. ABCD-33-21234-4652_00-2017-03.txt
2.SECA-11-4652_00-2017-03.txt
3. 8888-asde0-dswc-33-4444_55-2016-05.txt
我需要将这些文件移动到名称为XXXX_XX的目录中(如果不存在,请创建它们(
所以基本上我需要将它们移动到文件夹中,如下所示:
....\4652_00\ABCD-33-21234-4652_00-2017-03.txt
....\4652_00\SECA-11-4652_00-2017-03.txt
....\4444_55\8888-asde0-dswc-33-4444_55-2016-05.txt
我已经尝试了很多,但无法找到解决方案。感谢您的帮助。
这是一个包裹PowerShell一个衬里的cmd线解决方案。
批量使用时,%
符号必须加倍%%
。
我的内存磁盘 A 上的示例输出:
> tree /F
A:.
8888-asde0-dswc-33-4444_55-2016-05.txt
ABCD-33-21234-4652_00-2017-03.txt
SECA-11-4652_00-2017-03.txt
powershell -NoP -C "dir *.txt|where {$_.BaseName -match '-(d{4}_d{2})-20'}|%{MD $matches[1] -EA 0;$_|Move -Dest {$matches[1]}}"
> tree /F
A:.
├───4444_55
│ 8888-asde0-dswc-33-4444_55-2016-05.txt
└───4652_00
ABCD-33-21234-4652_00-2017-03.txt
SECA-11-4652_00-2017-03.txt
重要的是正则表达式-(d{4}_d{2})-20
,它与模式 -xxxx_xx-20 匹配,(xxxx_xx( 周围的括号标记我们感兴趣的组。
没有 PowerShell 脚本别名的更详细的版本:
Get-ChildItem *.txt |
Where-Object BaseName -Match '-(d{4}_d{2})-20'|
ForEach-Object {
mkdir $matches[1] -ErrorAction SilentlyContinue
$_ | Move-Item -Destination {$matches[1]}
}
@ECHO Off
SETLOCAL enabledelayedexpansion
SET "sourcedir=U:sourcedir"
SET "destdir=U:destdir"
FOR /f "delims=" %%a IN (
'dir /b /a-d "%sourcedir%*-????_??-*.txt" '
) DO (
SET "filename=%%a"
SET "filename=!filename:-= !"
SET "moved="
FOR %%b IN (!filename!) DO IF NOT DEFINED moved (
FOR /f "tokens=1*delims=_" %%p IN ("%%b") DO IF "%%q" neq "" (
ECHO MD "%destdir%%%p_%%q" 2>NUL
ECHO MOVE "%sourcedir%%%a" "%destdir%%%p_%%q"
SET "moved=Y"
)
)
)
GOTO :EOF
您需要更改sourcedir
和destdir
的设置以适合您的情况。
所需的 MD 命令仅用于测试目的ECHO
。验证命令正确后,将ECHO(MD
更改为MD
以实际创建目录。附加2>nul
以禁止显示错误消息(例如,当目录已存在时(
所需的 MOVE 命令仅用于测试目的ECHO
。验证命令正确后,将ECHO(MOVE
更改为MOVE
以实际移动文件。 附加>nul
以禁止显示报告消息(例如。1 file moved
(
dir
命令返回与文件掩码匹配的每个文件名,以%%a
,然后返回filename
。
然后,filename
中的每个-
都替换为空格,for..%%b
将文件名处理为空格分隔字符串的列表。
%%b
中的每个字符串都被标记化,第一个与string_string匹配的字符串被分配给%%p
和%%q
。如果%%q
为非空,那么我们找到了string_string,所以md
和move
并设置moved
标志以确保忽略找到的进一步匹配项。
请注意,这不会处理您有一个文件名像 something-abc_d-EFGH_JK-something的情况 - 它假设所需的目的地是 string_string的第一次出现,在这种情况下,这将是abc_d
,而不是EFGH_JK
。如果需要,这很容易解决。
根据对文件名结构的更正进行修订(无下划线 - 仅破折号(
@ECHO Off
SETLOCAL enabledelayedexpansion
SET "sourcedir=U:sourcedir"
SET "destdir=U:destdir"
FOR /f "delims=" %%a IN (
'dir /b /a-d "%sourcedir%????-*-????-??-*.txt" '
) DO (
SET "filename=%%a"
CALL :newname !filename:-= !
IF DEFINED newdir (
ECHO MD "!newdir!" 2>NUL
ECHO MOVE "%sourcedir%%%a" "%destdir%!newdir!"
)
)
GOTO :EOF
:newname
IF "%5" neq "" shift&GOTO newname
SET "newdir=%1-%2"
IF "%newdir:~4,1%" equ "-" IF "%newdir:~7%" equ "" IF "%newdir:~6,1%" neq "" GOTO :EOF
SET "newdir="
GOTO :eof
新代码查找序列-????-??-string-string并选取其中的最后一个。