繁体   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