根據條件移動資料夾

根據條件移動資料夾

我在一個資料夾中有很多 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\"

但我正在尋找更動態的解決方案。因此,請指導我找到解決方案。

PS註:- 即使是 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;一旦進入循環,我們設定一個名為fileas 的變量%%~nA,它只是參數%%A簡化為其檔案名稱。我們使用一個if語句來檢查該檔案的資料夾是否已經存在 - 如果不存在,我們使用 來建立資料夾md,然後我們使用另一個if語句來查看我們目前正在查看的檔案是否已經存在於我們的資料夾中剛剛驗證/製作- 如果沒有,我們將文件移動到資料夾move並抑制確認提示/y(這/y並不是真正必要的,因為我們以聲明開始if,但在我看來這是最佳實踐)。移動命令內建了重命名功能,因此我們只需使用它來遵循您想要的命名方案。

這裡最俗氣的部分是變數子字串 - 由於您的日期和位置是設定的字元數,我們只需計算這些字元並根據需要提取它們:
!file:~-6!只需獲取最後六個字元(我們的LOC 資訊),同時!file:~0,8!取得前八個字元(我們的 LOC 資訊)日期資訊)。唯一值得注意的是在使用延遲擴展的循環中使用感嘆號(因為這些是正在更改的變數);對於我們的靜態變數 (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"
}

我選擇獲得洛克###string 透過在下劃線上分割基本名稱,它本身會傳回一個二元素字串陣列。這1下標引用第二個元素。如果測試路徑失敗,我們創建資料夾,通過管道返回到輸出為空以避免螢幕顯示。然後移動項目就像聽起來那樣! :)

取得子項目

ForEach-對象

String.Split 方法

測試路徑

新物品

移動項目

相關內容