Powershell 将具有特定扩展名的文件移动到更高层次结构中的文件夹

Powershell 将具有特定扩展名的文件移动到更高层次结构中的文件夹,powershell,move,get-childitem,Powershell,Move,Get Childitem,我的所有文件都在特定文件夹中: 17\1\1\PRO 17\1\2\PRO 17\2\1\PRO xx\xx\xx\PRO 17岁是一年(所以18岁是下一年等) 第一个1是指定案例编号的文件夹(最多可为100) 第二个1是案例编号上的子部分 最后一个1中有一个文件夹PRO,其中包含所有数据 我们需要移动这些文件,但这些文件需要保留在各自的“PRO”文件夹中 例如: 17\1\1\pro\xxx\www\中的文件需要转到17\1\1\pro\movies 17\2\2\pro\xxdfsd

我的所有文件都在特定文件夹中:

17\1\1\PRO
17\1\2\PRO
17\2\1\PRO
xx\xx\xx\PRO
  • 17岁是一年(所以18岁是下一年等)
  • 第一个1是指定案例编号的文件夹(最多可为100)
  • 第二个1是案例编号上的子部分
最后一个1中有一个文件夹
PRO
,其中包含所有数据

我们需要移动这些文件,但这些文件需要保留在各自的“PRO”文件夹中

例如:

  • 17\1\1\pro\xxx\www\
    中的文件需要转到
    17\1\1\pro\movies
  • 17\2\2\pro\xxdfsdf\eeee\
    中的文件需要转到
    17\2\pro\movies
如果有文件要移动,则应创建“电影”文件夹

我需要获取文件全名的一部分,然后将文件移动到“movie”文件夹中。问题是我不知道如何拆分全名,向其中添加\movies并将文件移动到那里

这是我目前的代码:

Get-ChildItem -Path $mypath -Recurse -File -Filter $extension | select $_Fullname |
Move-Item -Force -Destination ($_Fullname.Split("pro"))

如果目标始终是“文件目录的祖父母目录的movies子目录”,则可以构建相对于文件位置的目标路径:

Get-ChildItem ... | ForEach-Object {
    $dst = Join-Path $_.Directory '..\..\movies'
    if (-not (Test-Path -LiteralPath $dst -PathType Container)) {
        New-Item -Type Directory -Path $dst | Out-Null
    }
    Move-Item $_.FullName -Destination $dst
}
如果
PRO
目录是您的锚点,您可以使用正则表达式替换,如下所示:

Get-ChildItem ... | ForEach-Object {
    $dst = $_.Directory -replace '^(.*\\\d+\\\d+\\\d+\\PRO)\\.*', '$1\movies'
    if (-not (Test-Path -LiteralPath $dst -PathType Container)) {
        New-Item -Type Directory -Path $dst | Out-Null
    }
    Move-Item $_.FullName -Destination $dst
}

如果您不知道有多少目录,我会这样做:

Get-ChildItem -Path $mypath -Recurse -File -Filter $extension | ForEach-Object {
    if ($_.FullName.IndexOf('\PRO\') -gt 0) {
        $Destination = Join-Path -Path $_.FullName.Substring(0,$_.FullName.IndexOf('\PRO\') + 5) -ChildPath 'movies';
        New-Item $Destination -ItemType Directory -ea Ignore;
        $_ | Move-Item -Destination $Destination;
    } else {
        throw ("\PRO\ path not found in '$($_.FullName)'");
    }
}
只要路径只有一次
\pro\
,这就可以正常工作。如果他们不止一次拥有它,比如
customer\pro\17\pro\17\1\pro\xx\yy\zz\www
,并且您需要最后一个索引,那么请使用
$\uu.FullName.LastIndexOf('\pro\')

如果您在
\pro\movies\
所在的目录前后都有
\pro\movies\
目录,那么您就有麻烦了。您可能需要找到不同的参考点。

使用一组文件夹

17\1\1\PRO
17\1\2\PRO
17\2\1\PRO
你可以试试下面的方法

$RootPaths = Get-ChildItem -Path C:\folder\*\*\*\pro
$rootpath
将包含上面提到的所有3个路径,下面的代码将所有文件移动到适当的目录

ForEach( $Path in $RootPaths)
{
    $Movies = Join-Path $Path -Child "Movies"
    If( -not (Test-Path $Movies ) ) { New-Item -Path $Movies -ItemType Directory }

    Get-ChildItem -Path $Path -Recurse -File -Filter $Extension | 
        Move-Item -Path $_.FullName -Destination "$( $Path )\Movies"
}

这样,文件的级别降低了多少并不重要。他们总是被移动到同一个目录。

祖父母目录并不总是确定的。在一个pro文件夹中可以有数千个目录,每个目录中的多个子目录会被拆分成更多的目录。永远无法确定有多少子文件夹如果是这种情况,只需将目标子目录作为参数输入cmdlet/函数。对于第二个版本,您需要在移动之前插入
If(!(测试路径$dst)){md$dst | out Null}
+1.@LotPings的确如此。我错过了“如果有文件要移动,则应创建电影文件夹”部分。感谢heads up.IMO,您应该从
移动项目
中删除
-Path
,因为它已经从管道接收文件对象。您不能使用$rootpath,因为您事先不知道根路径是什么。这取决于您所在的子目录:17\1\1\pro收集17\2\1\pro收集下面的所有内容在Powershell中,星号字符可用于指代所有文件夹。这意味着
$rootpath
将包含从根目录向下具有2级pro文件夹的所有文件夹。所述缺陷仍然存在,并且您的脚本也存在相同的问题-如果未首先创建movies文件夹,则文件将移到名称movies。确定,添加了目录创建。发现得很好。整个路径结构中只有1个pro,因此这将起作用。这将创建一个文件
movies
,以适当的位置显示移动文件的内容。您应该先对文件夹$Destination执行测试路径,然后使用它自己的名称移动该文件,可能会检查它是否已经存在,以避免覆盖其他子文件夹中的相同名称。在移动项行前面插入
if(!(测试路径$Destination)){md$Destination | out Null}
。@LotPings Fair,我错过了这一点。
ForEach( $Path in $RootPaths)
{
    $Movies = Join-Path $Path -Child "Movies"
    If( -not (Test-Path $Movies ) ) { New-Item -Path $Movies -ItemType Directory }

    Get-ChildItem -Path $Path -Recurse -File -Filter $Extension | 
        Move-Item -Path $_.FullName -Destination "$( $Path )\Movies"
}