我在一个文件夹中有许多 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!
抓取前八个字符(我们的日期信息)。唯一值得注意的另一件事是在使用延迟扩展的循环中使用感叹号(因为这些是正在变化的变量);对于我们的静态变量(dir
和des
),百分号始终没问题。
希望这能满足您的要求,或者至少让您走上正确的轨道。
答案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下标引用第二个元素。如果测试路径失败,我们创建文件夹,并将返回管道传输到出空值以避免屏幕显示。然后移動項目正如其名!:)