创建文件夹并将文件移动到基​​于文件名的文件夹结构

时间:2019-02-08 02:34:04

标签: powershell

我有一个包含视频文件的文件夹,我需要为每个文件创建一个文件夹,该文件夹的名称与该文件的名称相同(减去文件扩展名),然后将该特定文件移至与其关联的文件夹中。

最终结果应消除根目录中的所有文件,并且每个文件夹应包含一个文件。

示例文件夹应开始如下所示:

  • 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变量来指定目标路径。这不起作用,因为它导致将所有文件移动到一个文件夹中,这是从第一个Foreach循环传递到$basename变量的最后一个对象。

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

这种方法很有意义,但是由于我有限的知识和经验,我无法找到实现目标的另一种方法。我开始研究嵌套的ForEach循环,但是我猜想有一种更简单的方法可以实现此目的。

我在第二个循环中尝试了以下命令

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 :(得分:0)

这可能不是执行此操作的最佳方法,但它确实可以满足我的需要。我太专注于使用确切的文件名,包括文件名和通配符满足要求时的.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
}

答案 1 :(得分:0)

您的回答很好,但是无需创建带有属性名称的文件。

您只需在循环内选择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

答案 2 :(得分:0)

我将进一步简化此过程,并在此过程中消除使用Join-Path cmdlet这样的错误路径名的风险:

$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
}