Home > OS >  Move files that are all in one folder based on file/folder structure in txt file using PowerShell sc
Move files that are all in one folder based on file/folder structure in txt file using PowerShell sc

Time:11-27

What I'm trying to achieve is following:

I have a few thousand files in one "Global" folder. Example:

PS D:\Backup\Global> dir

    Directory: D:\Backup\Global

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
------        19.8.2016.     08:25         282208 CBR.docx
------        17.9.2018.     13:37         254803 CMZ.docx
------         6.6.2017.     07:46         191928 Ginekologija.docx
------        6.12.2019.     08:16         192412 HES.docx
------        19.2.2021.     11:56         192925 Hitna medicinska pomoć.docx
*
*
*

And I need to move them to folders/subfolders (that don't exist yet) according to Structure.txt file.

Content of Structure.txt:

D:\Backup\Structured\1 Word files\1 Планови 2018\Prijedlog godišnjeg plana obuke\CBR.docx
D:\Backup\Structured\1 Word files\1 Планови 2018\Prijedlog godišnjeg plana obuke\CMZ.docx
D:\Backup\Structured\1 Word files\1 Планови 2018\Prijedlog godišnjeg plana obuke\Ginekologija.docx
D:\Backup\Structured\1 Word files\1 Планови 2018\Prijedlog godišnjeg plana obuke\HES.docx
D:\Backup\Structured\1 Word files\1 Планови 2018\Prijedlog godišnjeg plana obuke\Hitna medicinska pomoć.docx
*
*
*

Below are the actions that I suppose I need to perform:

  1. Read the Structure.txt file
  2. For every line in txt check if folders/subfolders exist, create when it doesn't
  3. Move file from "Global" folder to folder referenced in "Structure.txt"

I have found a similar script but something is not working in my case...

$des = "$ENV:D:\Backup\Structured"
$safe = Get-Content "$ENV:D:\Backup\Global\Structure.txt" 
$safe | ForEach-Object {
    #find drive-delimeter
    $first = $_.IndexOf(":\");
    if ($first -eq 1) {
        #stripe it
        $newdes = Join-Path -Path $des -ChildPath @($_.Substring(0, 1)   $_.Substring(2))[0]
    }
    else {
        $newdes = Join-Path -Path $des -ChildPath $_
    }
    $folder = Split-Path -Path $newdes -Parent
    $err = 0
    #check if folder exists"
    $void = Get-Item $folder -ErrorVariable err  -ErrorAction SilentlyContinue
    if ($err.Count -ne 0) {
        #create when it doesn't
        $void = New-Item -Path $folder -ItemType Directory -Force -Verbose
    }
    $void = Move-Item -Path $_ -destination $newdes -Force
}

How can I achieve this using powershell script?

Appreciate help on this! Thanks in advance.

CodePudding user response:

Assuming your structure,txt file may contain different paths for the destinations, you could do below to move the files:

$sourceFolder = 'D:\Backup\Global'

# read the structure.txt file and loop through the entries
Get-Content -Path 'D:\Test\structure.txt' -Encoding utf8 | ForEach-Object {
    # create the full file path and name to be found in the source folder
    $file = Join-Path -Path $sourceFolder -ChildPath ([System.IO.Path]::GetFileName($_))
    if (Test-Path -Path $file -PathType Leaf) {
        # file found; split the path from the filename as found in structure.txt
        $targetFolder = [System.IO.Path]::GetDirectoryName($_)
        # create the path if it did not already exist
        $null = New-Item -Path $targetFolder -ItemType Directory -Force
        # move the file
        Move-Item -Path $file -Destination $targetFolder
    }
}
  • Related