根据条件移动文件夹

根据条件移动文件夹

我在一个文件夹中有许多 Excel 文件,如下所示。

+----------------------+
| 01012019_LOC001.xlsx |
| 01012019_LOC002.xlsx |
| 01012019_LOC003.xlsx |
| 02012019_LOC001.xlsx |
| 02012019_LOC002.xlsx |
| 02012019_LOC003.xlsx |
| 03012019_LOC001.xlsx |
| 03012019_LOC002.xlsx |
| 03012019_LOC003.xlsx |
+----------------------+

日期加位置组合结构DDMMYYYY_LOCXXX

我想将这些文件移动到类似于以下结构的各自文件夹中。

MAIN_FOLDER
|
|-LOC001
  |-01012019
  |-02012019
  |-03012019
  |
|-LOC002
  |-01012019
  |-02012019
  |-03012019
  |
|-LOC003
  |-01012019
  |-02012019
  |-03012019
|

我可以用 一次转移一个for /r %d in (01012019_LOC001.xlsx) do move "%d" "C:MAIN_FOLDER\LOC001\01012019\"

但我正在寻找一个更具活力的解决方案。因此,请指导我找到解决方案。

PSNote:即使一个 powershell 答案也足够了。

答案1

为此,您需要循环遍历具有延迟扩展的文件。除非您还想从子文件夹中提取文件,否则我会避免使用标志,/r因为for它是递归的。主要问题是将文件名拆分开,因为每一半都是单独的信息。它看起来像这样:

@echo off

set "dir=C:\Your\Excel\File\Directory"
set "des=C:\MAIN_FOLDER"

setlocal enabledelayedexpansion
for %%A in (%dir%\*.xlsx) do (
    set "file=%%~nA"
    if not exist "%des%\!file:~-6!" md "%des%\!file:~-6!"
    if not exist "%des%\!file:~-6!\!file:~0,8!.xlsx" move /y "%dir%\%%~nxA" "%des%\!file:~-6!\!file:~0,8!.xlsx"
)

这是一个批处理解决方案,因此您可以将其复制并粘贴到记事本中,然后将其保存为.bat而不是.txt

首先,我为dir(目录;您的 Excel 文件当前所在的位置)和des(目标;您想要创建文件夹和移动文件的位置)设置了变量 - 您需要编辑这些值以反映您的环境。在做任何其他事情之前,我们使用,setlocal enabledelayedexpansion因为我们正在使用每次循环迭代都会更改值的变量。for将循环遍历目录顶级文件夹中的所有 excel 文件并将它们分配给参数%%A;一旦进入循环,我们将设置一个名为的变量,file%%~nA只是参数%%A简化为其文件名。我们使用一个if语句来检查该文件的文件夹是否已经存在 - 如果不存在,我们使用创建文件夹md,然后我们使用另一个if语句来查看我们当前正在查看的文件是否已经存在于我们刚刚验证/创建的文件夹中 - 如果不存在,我们将文件移动到文件夹move并使用取消确认提示/y(这/y不是真正必要的,因为我们用一个语句开始if,但在我看来这是最佳实践)。移动命令内置了重命名,所以我们只需使用它来遵循您想要的命名方案。

这里最俗气的部分是变量子字符串 - 由于您的日期和位置是固定数量的字符,我们只需计算这些字符并根据需要提取它们:
!file:~-6!只抓取最后六个字符(我们的 LOC 信息),而!file:~0,8!抓取前八个字符(我们的日期信息)。唯一值得注意的另一件事是在使用延迟扩展的循环中使用感叹号(因为这些是正在变化的变量);对于我们的静态变量(dirdes),百分号始终没问题。

希望这能满足您的要求,或者至少让您走上正确的轨道。

参考:为了变量子串移动

答案2

为了完整起见,这里有一个电源外壳版本:

$Source = 'C:\Source'
$Dest   = 'C:\Destination'

Get-ChildItem $source -filter *.xls | foreach{
   $FolderName = $_.Basename.Split('_')[1]
   If (!(Test-Path "$Dest\$FolderName")) {
      New-Item -Path $Dest -Name $FolderName -ItemType Directory | out-null
   }
   Move-Item $_.FullName "$Dest\$FolderName"
}

我选择获得位置###通过在下划线处拆分基本名称来获取字符串,这本身会返回一个双元素字符串数组。1下标引用第二个元素。如果测试路径失败,我们创建文件夹,并将返回管道传输到出空值以避免屏幕显示。然后移動項目正如其名!:)

获取子项

ForEach 对象

String.Split 方法

测试路径

新物品

移動項目

相关内容