Перемещение файлов в новую папку внутри родительского элемента на основе критериев

В настоящее время я работаю над проектом в Powershell, с которым я действительно не очень знаком. Я подошел довольно близко и немного огляделся, чтобы приблизить меня, но я в тупик на этом важном событии.

Цель состоит в том, чтобы рекурсивно искать в каталоге файлы с префиксом "\_7Y_"(это было сделано другим сценарием, который я написал, основываясь на возрасте файлов) и создать новый подкаталог в родительском файле, а затем переместить его туда. Например, если у меня есть ~\desktop\old\\_7Y_OldFile.txtЯ хочу, чтобы этот файл ~\desktop\old\\_7Y_\\_7Y_OldFile.txt и я хочу, чтобы он делал это для каждого файла рекурсивно.

Мой сценарий в настоящее время создает папки, как и ожидалось, но выбирает только одну из новых папок для перемещения элемента. Я думаю, это связано с тем, что переменная $ child выбирает только это одно значение, так как после перемещения файла сценарий продолжается, но получает ошибки, пытаясь найти файлы для их перемещения. Если не считать ручного указания каждого родителя (этот процесс в конечном итоге будет автоматизирован), мне было интересно, что можно сделать, чтобы сделать различие между каждым $ child для перемещения.

Я также понимаю, что мне не нужно делать новый предмет, а затем перемещать предмет, пока я использую силу, но это также не было моим опытом. Любая помощь будет оценена.

Я прошу прощения за странное форматирование и методы - я действительно изучал PowerShell на слух на ходу.

[CmdletBinding()]
Param(
[Parameter(mandatory=$true)]
[ValidateScript({Test-Path $_ -PathType 'any'})]
[string] $InputFilePath
)
#this sets the filepath parameter to mandatory, so you will need to input 
your own filepath!

$directoryInfo = Get-ChildItem $InputFilePath -recurse | Measure-Object 
$7Yno = Get-ChildItem $InputFilePath -recurse | Where-Object {$_.Name -like '_7Y_*.*'} | Measure-Object
#These are used as the conditions for the if statements
#directoryInfo gets the number of files in the directory; 7Yno gets the number of files prepended with _7Y_ in the directory

$Confirmation = Read-Host "Are you SURE you want to proceed with this operation? All selected files in the given directory will be moved to new directories! This action is irreversable. Your selected directory is $InputFilePath. Enter 'Yes' to proceed"

if ($Confirmation -eq "Yes") {

    if ($directoryInfo.count -gt 0 -and $7Yno.count -gt 0){   #Check: Files in directory and files prepended with _7Y_ in directory.

    $children = @((Get-ChildItem $InputFilePath -recurse | 
        Where-Object {$_.Name -like "_7Y_*.*"}).directory.fullname | 
            Get-Unique)
    $Files = @(Get-ChildItem $children -recurse | 
        Where-Object {$_.Name -like "_7Y_*.*"})

        foreach($child in $children){
            $7yPath = "$child\_7Y_"
            New-Item -itemtype Directory -path $7yPath -force
        }
        foreach($file in $Files){
            Move-Item $file.fullname -destination $7yPath -force
        }
    }

    if ($directoryInfo.count -gt 0 -and $7Yno.count -eq 0){   #Check: Files in directory, but no files prepended with _7Y_ in directory.
    Read-Host "There are no files prepended with _7Y_ in this directory!"
    }

    if ($directoryInfo.count -eq 0){                            #Check: No files in directory.
    Read-Host "There are no files in this directory!"
    }
}

1 ответ

Решение

Вы IMO усложняете вещи.

  • Get-ChildItem с префиксом рекурсивно
  • если имя родительской папки не совпадает с префиксом
    • проверьте, существует ли папка, если не создайте ее
    • переместить файл в папку

РЕДАКТИРОВАТЬ: оптимизировать скрипт с использованием только один раз "$($_.Directory)\$Prefix"

Push-Location 'X:\Folder\to\start'
$Prefix = '_7Y_'
Get-ChildItem -File -Filter "$Prefix*" -Recurse | 
  Where-Object {$_.Directory.Name -ne $Prefix} |
    ForEach-Object {
      $DirPrefix = "$($_.Directory)\$Prefix"
      If(!(Test-Path $DirPrefix)){
        Md $DirPrefix | Out-Null
      }
      $_ | Move -Destination $DirPrefix

    }

Образец дерева /F перед

└───one
    │   _7Y_one.txt
    │
    └───two
        │   _7Y_two.txt
        │
        └───three
            │   _7Y_three.txt
            │
            └───four
                    _7Y_four.txt

И после запуска скрипта

───one
   ├───two
   │   ├───three
   │   │   ├───four
   │   │   │   └───_7Y_
   │   │   │           _7Y_four.txt
   │   │   │
   │   │   └───_7Y_
   │   │           _7Y_three.txt
   │   │
   │   └───_7Y_
   │           _7Y_two.txt
   │
   └───_7Y_
           _7Y_one.txt

Объясняя строку:

If(!(Test-Path "$($_.Directory)\$Prefix"))
  • При обращении к свойству объекта $_.Directory внутри строкового выражения вы должны заключить его в $() быть однозначным / оценка силы.
  • Test-Path возвращает $true/$false, для отмены условия либо используйте -not в случае - или - отрицать с !(Test-Path ...)
Другие вопросы по тегам