簡體   English   中英

Powershell - 根據文件名將文件分類到目錄中

[英]Powershell - Sort files into directory based on file name

我正在嘗試根據文件名和分隔符將我的文件分類到唯一的字典中。

文件名遵循以下結構: LocationName-DP-Category-SL

其中... -是分隔符

  • 位置名稱是可變長度,從不包含空格
  • DP是兩個字母的部門代碼
  • 類別是可變長度,從不包含空格
  • S是單字母尺寸代碼
  • L是長度

類別之后的所有內容都無關緊要,因為文件名末尾通常有一些額外的亂碼要忽略。

我想為文件路徑的 LocationName-DP-Category 部分的每個發現的變體創建一個文件夾結構並對其進行排序,如下所示:

  • 父文件夾:LocationName
  • 子文件夾:DP
  • 子子文件夾:類別

試圖讓它不那么僵化,因為它經常在不同批次的文件上運行。 這是我所擁有的:

##GET USER INPUT FROM DIALOG
Add-Type -AssemblyName System.Windows.Forms
$browser = New-Object System.Windows.Forms.FolderBrowserDialog
$null = $browser.ShowDialog()
$path = $browser.SelectedPath + "\"

##SORT ALL FILES
Get-ChildItem -Path $path *-*-*-*-*.* |
  Where-Object BaseName -match '(?<store>\w+)\-+(?<dept>\w+)\-+(?<category>\w+)*.*'|
    Group-Object {$Matches["store"]+'-'+$Matches["dept"]+'-'+$Matches["Category"]}|
      ForEach-Object{mkdir $_.Name;$_.Group|Move-Item -Dest $_.Name}

非常感謝您的幫助,幾個月來一直在摸索我的頭。

謝謝

...最初我也考慮過 group-object 但我認為這沒有必要,認為這更簡單:

#Get Source Files
$files = get-childitem -Path [path]
#Set target root path
$targetPathRoot = "C:\tmp\"
#Loop through array of files
foreach ($file in $files){
    #Split the filename 
    $split = $file.name -split "-"
    #Build the target path
    $newFullPath = $targetPathRoot + $split[0] + '\' + $split[1] + '\' + $split[2]
    #If path exists move item, otherwise create path and move item
    If (Test-Path $newFullPath){
        $null = move-item -Path $file.psPath -Destination $newFullPath
    }
    Else {
        $null = new-item -ItemType Directory -Path $newFullPath -Force
        $null = move-item -Path $file.psPath -Destination $newFullPath
    }
}

假設“LocationName”、“DP”或“Category”部分都不包含連字符,您可以像這樣為文件創建新路徑:

# 'LocationName-DP-Category-S-L-blah.ext' --> LocationName\DP\Category
$_.BaseName -replace '^(\w+-\w{2}-\w+).*', '$1' -replace '-', '\'

然后你的代碼可以變成

Add-Type -AssemblyName System.Windows.Forms
$browser = New-Object System.Windows.Forms.FolderBrowserDialog
$null = $browser.ShowDialog()
$path = $browser.SelectedPath
$browser.Dispose()  # remove from memory when done

# the root path for the (new) subfolders and files
$destination = 'X:\SomeWhere'
if (![string]::IsNullOrWhiteSpace($path)) {
    Get-ChildItem -Path $path -Filter '*-*-*-*-*.*' -File | ForEach-Object {
        $subPath   = $_.BaseName -replace '^(\w+-\w{2}-\w+).*', '$1' -replace '-', '\'
        $targetDir = Join-Path -Path $destination -ChildPath $subPath
        # create the new path if it does not already exist
        $null = New-Item -Path $targetDir -ItemType Directory -Force
        # move the file
        $_ | Move-Item -Destination $targetDir
    }
}
else {
    Write-Host "Folder dialog cancelled"
}

注意:在File System上, New-Item -Path $targetDir -ItemType Directory -Force將創建新文件夾,或者返回對現有文件夾的引用。 在這種情況下, -Force開關允許您在這種情況下不必使用Test-Path 請注意,在處理其他系統(例如注冊表項)時,您不應該使用該技術

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM