Создание папок и перемещение файлов в структуру папок на основе имени файла - PullRequest
0 голосов
/ 08 февраля 2019

У меня есть папка с видеофайлами, мне нужно создать папку для каждого файла, в которой имя папки совпадает с именем файла (без расширения файла), и переместить этот конкретный файл в соответствующую папку.

Конечный результат должен исключить все файлы в корне, и каждая папка должна содержать один файл.

Пример папки должен выглядеть примерно так:

  • c: \ videos \video1.avi
  • c: \ videos \ video2.mov
  • c: \ videos \ video3.mkv

А затем выглядело так:

  • c: \ videos \ video1 \ video1.avi
  • c: \ videos \ video2 \ video2.mov
  • c: \ videos \ video3 \ video3.mkv

Все работает, кроме последнего шага перемещения файлов в связанные с ними папки.

В этом втором ForEach я пытаюсь указать путь назначения, используя переменную $basename, использованную в первом цикле.Это не работает, поскольку приводит к перемещению всех файлов в одну папку, которая является последним объектом, переданным в переменную $basename из 1-го цикла Foreach.

foreach ($filename in $VideoFiles) {
    Move-Item -Path \\server1\Video\Staging\$filename -Destination \\server1\Video\Staging\$basename -verbose 
}

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

Я попробовал следующую команду во 2-м цикле

Move-Item -Path \\server1\Video\Staging\$filename -Destination \\server1\Video\Staging\$filename -verbose

Но, конечно, этопеременная хранит имя файла (включая расширение) и не перемещает файлы.

Любая помощь будет принята с благодарностью ..!

Get-ChildItem -Path \\server1\video\staging | ForEach-Object {$_.basename} | Out-File \\server1\video\videonames.txt

$VideoNames = Get-Content \\server1\video\videonames.txt

Get-ChildItem -Path \\server1\video\staging | ForEach-Object {$_.name} | Out-File \\server1\video\videosfiles.txt

$VideoFiles = Get-Content \\server1\video\videosfiles.txt

foreach ($BaseName in $VideoNames) {
    New-Item -ItemType Directory -Path \\server1\Video\Staging\$BaseName 
}

foreach ($filename in $VideoFiles) {
    Move-Item -Path \\server1\Video\Staging\$filename -Destination \\server1\Video\Staging\$basename -verbose 
}

Ответы [ 3 ]

0 голосов
/ 08 февраля 2019

Ваш ответ хороший, но нет необходимости создавать файл с именами свойств в.

Вы можете просто выбрать свойство BaseName внутри цикла, то есть вам нужен только один foreach:

$Source = '\\server1\Video\Staging'

foreach ($File in Get-ChildItem -Path $Source) {
    $FileBaseName = $File.BaseName

    if(!(Test-Path $Source\$FileBaseName)){
        New-Item -ItemType Directory -Path $Source\$FileBaseName -WhatIf
    }
    Move-Item -Path $Source\$FileBaseName.* -Destination $Source\$FileBaseName -WhatIf
}

Примечание. Удалите -WhatIf, если хотите, чтобы код выполнял действия

0 голосов
/ 08 февраля 2019

Я бы немного упростил это, и в процессе этого исключил бы риск создания неправильных имен путей с помощью командлета Join-Path, например:

$Source = '\\server1\Video\Staging'

(Get-ChildItem -Path $Source -File) | ForEach-Object {
    $destination = Join-Path -Path $Source -ChildPath $_.BaseName

    if(!(Test-Path $destination)){
        New-Item -ItemType Directory -Path $destination | Out-Null
    }
    $_ | Move-Item -Destination $destination
}
0 голосов
/ 08 февраля 2019

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

#Creates a text file list of the file names and defines a variable for it.
Get-ChildItem -Path \\server1\video\staging | ForEach-Object {$_.basename} | Out-File \\server1\video\videonames.txt
$VideoNames = Get-Content \\server1\video\videonames.txt

#Creates the folder structure based on file names
$Folder = foreach ($BaseName in $VideoNames){
    New-Item -ItemType Directory -Path \\server1\Video\Staging\$BaseName   
}

#Moves each file in the folder with the same name.
foreach ($File in $VideoNames){
    Move-Item -Path \\server1\Video\Staging\$file.* -Destination \\server1\Video\Staging\$file -verbose
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...