我一直在试图弄清楚如何制作一个可以“看到”文件名的一部分的 dos 命令,然后创建一个文件夹并对其中包含文件名该部分的每个文件进行排序。
每个文件名都有以下字符(不包括扩展名):
3 个字母, 5 个数字, 1 个字母, 1 个数字
例如:BBB12345B0
文件名中的每个字母和数字可以不同,但文件名始终具有相同的构造。
该脚本要做的就是仅识别这 5 位数字,然后根据这 5 位数字创建一个文件夹,然后将这些文件移动到该文件夹中。
以下是我在网上找到的:
@echo 关闭 对于/f“delims=”%% a在('dir /b /ad')中执行( 如果不是“%%~fa”=="%~f0"( md "%%~na" 2>nul 如果存在“%%a”移动“%%~na.*” “%%~na” ) )
这很好用,只是需要使用整个文件名来创建文件夹并对文件进行排序。我希望脚本只使用 5 位数字来做同样的事情。
我尝试过在这个脚本中使用“token”。还使用了一些其他方法,但都不能正常工作。我对这种批处理脚本也不太熟悉。有人能帮我吗?
答案1
在使用 CMD 脚本进行更改之前,这里有一种不同的方法,使用JP Software 的 TCC/LE,另一种命令解释器:
@echo off
for %file in ([a-z][a-z][a-z][0-9][0-9][0-9][0-9][0-9][a-z][0-9].*) do (
mkdir 2>NUL "%@instr[3,5,%file%]"
ren "%file%" "%@instr[3,5,%file%]\%file%"
)
请注意,相当长的通配符符合您的规范,并且不会包含具有不同字母数字模式的文件名。限制较少的通配符是[?][?][?][?][?][?][?][?][?][?].*
,它匹配每个长度正好为 10 个字符的文件名,不带扩展名。还请注意,不需要显式/a:-d
使用for
,因为排除目录已经是默认设置。
使用命令/n
选项ren
来显示不移动文件时会发生什么。
顺便说一句,用dir /b
解析的输出是疯狂的。即使在 Microsoft 的 CMD 中,它本身也会搜索通配符。for
for
进一步阅读
答案2
你好,JdeBP 和 Martin,
我尝试了 JdeBP 提供的两种解决方案,但都出现了“文件未预期”错误。Martin 提供的 powershell 选项看起来是个不错的选择。如果我需要更多地使用这种批处理脚本,我会进一步研究它
答案3
在 PowerShell 中:
$files = gci . | where {!$_.psIsContainer}
foreach ($file in $files) {
$dir = $file.Name.Substring(3, 5)
if (!(test-path -path $dir)) {
mkdir $dir
}
mv $file $dir
}
假设您的文件位于当前目录中。
答案4
如果可能的话,您应该改用 PowerShell,它可以安装在 WinXP 上,并且默认包含在 Windows Vista 及更高版本中,因此无需安装任何东西。它有很多工具,使许多批处理中的麻烦工作变得非常简单。它还允许您在紧急情况下使用 com-objects 和 .net 库。
它还允许您使用正则表达式,这使得您想要做的事情变得更加容易,最重要的是,您可以在其中使用常规的批处理工具,例如“mkdir”(如果您愿意),尽管它很少需要。
如果您在网上搜索“powershell 教程”等,会发现很多不错的教程。
(如果我以后有时间,我会编写一个简单的脚本来完成您需要的任务。)
编辑:而且它比批处理更具可读性^^
编辑2:可以完成您需要的简短脚本:
$dir="X:\Your\Path";
get-childitem $dir | %{
$file=$_;
if(-not $file.PSIsContainer)
{
if($file.PSChildName -match "^.*(\w{3})(\d{5})(\w{1})(\d{1}).*$")
{
$folder = "$($file.PSParentPath)\$($matches[2])";
if(test-path $folder)
{
Move-Item "$($file.PSPath)" "$folder\$($file.PSChildName)";
}
else
{
mkdir $folder;
Move-Item "$($file.PSPath)" "$folder\$($file.PSChildName)";
}
}
}
}