BAT文件以从文件名中提取文件夹名称并将文件移动到该文件夹​​中


2

我对Windows bat文件编程不是很熟悉,对此我将不胜感激。

我需要一个bat文件来执行以下操作:

  • 从文件名中提取文件夹名称-例如,从文件名“ 123-Chemistry-101.rep”中提取化学。“-”可用于表示令牌的开始和结束。
  • 将同一文件移到名为化学的文件夹中。化学将是所有报告所在的子目录。

我可能可以做第二部分(我在本网站上找到),但是第一部分超出了我的能力。

例如,对于(* .rep)中的/ RU:\ Test %% f,请复制%% f U:\ test \ Chemistry \

问候,杜兰德

Answers:


3

您要求Batch,但我回答是Powershell因为我认为今天Batch对于这样的任务有些过时了,希望您的系统支持Powershell

$rootDir = "U:\Test"

$files = Get-ChildItem $rootDir -Filter *.rep

foreach($file in $files) {
  $folder = $file.toString().split("-")[1]
  $sourcefile = "$rootDir\$file"
  $targetdir = "$rootDir\$folder"
  if(!(Test-Path -Path $targetdir )){
    New-Item -ItemType directory -Path $targetdir
  }
  Move-Item $sourcefile $targetdir
}

编辑@Karan:

递归(保留子目录树):

$rootDir = "U:\Test"

$files = Get-ChildItem $rootDir -Filter *.rep -Recurse

foreach($file in $files) {
  $sourcefile = $file.Fullname
  $filepath = $file.PSParentPath
  $newfoldertocreate=$file.toString().split("-")[1]
  if(!(Test-Path -Path $filepath\$newfoldertocreate)){
    New-Item -ItemType directory -Path $filepath\$newfoldertocreate
  }
  Move-Item $sourcefile $filepath\$newfoldertocreate
}

批处理永远不会死!:P(顺便说一句,至少在这种情况下,我的批处理代码比PS短得多。它还处理子文件夹中的.REP文件,而此代码仅适用于单个级别。我尝试将-Recurse添加到Get-ChildItem,但它没有“工作不正常。您能建议如何处理吗?)
Karan 2015年

@Karan:我知道Batch永远不会死...这里是您要求的递归编辑。诀窍是获取子目录中文件的完整路径。然后,目标目录如何?应该有子文件夹吗?假设此处为“否”。我的脚本中的“太多”行是为了使其非常清晰...但是可以将其缩短...
user2196728 2015年

我在Reports文件夹(rootDir)中使用子文件夹进行了测试,但失败了。需要明确的是,rootDir是D:\New folder。我有D:\ New文件夹\ 123-Chemistry-101.rep,D:\ New文件夹\ 123-Phys Ed-101.rep,D:\ New文件夹\ New文件夹\ 123-Chemistry-101.repD: \ New文件夹\ New文件夹\ 123-Phys Ed-101.rep(在两个级别的文件夹中只有4个文件)。
卡兰2015年

我是否必须了解文件夹名称和文件名称中有空格?;)
user2196728

是的,很明显。:)(顺便说一句,我希望您理解我不是问这个问题的人,因此,如果您没有时间或意愿,请随时忽略这些增强要求。我只是想了解如何做到这一点即使我已经用3行批处理文件完成了它,PowerShell也能达到同样的效果。)
Karan 2015年

2

Reports文件夹的父文件夹运行此批处理文件:

for /f "delims=" %%a in ('dir /b /s "Reports folder\*.rep"') do for /f "tokens=2 delims=-" %%i in ("%%~a") do (
    if not exist "%%~dpa%%i\" md "%%~dpa%%i"
    move "%%~a" "%%~dpa%%i\"
)

%% a和%% i是两个for循环中使用的变量。前者包含.REP文件的完整路径(由外部循环提供),后者包含从文件名中提取的文件夹名称(由内部循环)。

for /? 是任何有兴趣的人真正应该寻求更多帮助的内容(请注意,在批处理文件中,%符号会加倍):

%~I  - expands %I removing any surrounding quotes (")
%~dI - expands %I to a drive letter only
%~pI - expands %I to a path only

那么“ %%〜dpa %% i”是什么意思?假设由dir命令定位的.REP文件之一是"C:\Reports folder\123-Chemistry-101.rep"

%%〜dpa表示文件的驱动器号和路径减去周围的引号,即C:\Reports folder\

如上所述,%% i是从文件名中提取的文件夹名称(两个连字符定界符之间的任何内容),因此在这种情况下Chemistry

将所有内容放在一起,“ %%〜dpa %% i”会为此文件扩展为"C:\Reports folder\Chemistry",因为这是我们要将文件移动到的位置。


注意:即使.REP文件存在于Reports文件夹的子文件夹中,它也可以工作,并且将在查找此类文件的每个级别上创建使用者名称子文件夹。
卡兰,2015年

很好,但是我会给出解释性的注释来帮助您阅读,%%~dpa%%i 在%%〜dpa部分中,“ a”是变量,而d和p是代码。读者应该知道%〜或%%〜代码(据我所知)永远不会以%结尾,因此,读者应查看%%〜dpa是什么,然后%% i是什么。显示文件属性的代码“ a”,例如%〜a1。因此,只需说明您的“ a”是变量a。有时批处理变得如此复杂,我不得不回显并运行它以弄清楚甚至是关于语言的问题!好东西
barlop 2015年

@barlop:我添加了一些东西,但实际上人们将不得不学习,for /?并且如您所说,通过自由地使用echo调试文件。这里可以解释的内容是有限的,读者需要付出一些努力。
卡兰,2015年

您编写了“内部循环” <---它标记了一个字符串,但是我猜该内部for语句中没有迭代,在这种情况下,我认为内部for语句并不是一个循环。虽然在技术上,我认为你是对的这是一个循环,而是因为它可以与多个项目潜在的处理
barlop

@barlop:如果将其视为一个for-do循环,则第二个循环确实具有主体,第一个循环的主体由第二个循环组成。无论如何,挂在这样琐碎的海事组织上毫无意义。就我而言,这对理解代码没有任何影响。
卡兰2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.