move files with specific extension to folder in higher hierarchy

泄露秘密 提交于 2019-12-06 16:43:43

If you don't know how many directories there are, I would do something like this:

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)'");
    }
}

This will work fine as long as your paths only have \pro\ once. If they have it more than once like customer\pro\17\pro\17\1\1\pro\xx\yy\zz\www and you need the last index, then use $_.FullName.LastIndexOf('\pro\').

If you've got \pro\ directories both before and after the directory that .\pro\movies\ is in, well, you're in trouble. You'll probably have to find a different point of reference.

If the destination is always "movies subdirectory of the grandparent directory of the file's directory" you can build the destination path relative to the file's location:

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
}

If the PRO directory is your anchor you could use a regular expression replacement like this instead:

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
}

With a set of folders

17\1\1\PRO
17\1\2\PRO
17\2\1\PRO

You could try the following

$RootPaths = Get-ChildItem -Path C:\folder\*\*\*\pro

$RootPaths will then contain all 3 paths mentioned above and the code below will move all files to the appropriate directory.

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

This way it doesn't matter how many levels down your files are. They always get moved to the same directory.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!