Search code examples
powershellfile-manipulation

Powershell Move file to new destination based on trimmed file name


I have a folder where files get dropped, I wish to pull the files from that folder and move to a new folder based on part of the file name. If the new folder is missing then create it.

I have attempted to put together the below, however it throws an error about the path already existing and doesn't move the file.

File names can be any thing with out pattern except the last 16 characters of the file, I am removing these and using the remaining as the folder name. I am really new to scripting so if i have made a silly mistake explanations are appreciated.

Edit I have played with different orders of operations, added a "-Force" to the new item command, tried with using "Else" and not "If (!(". I am now at the point where it proudly displays the new directory and then stops. Could i add the move-item part to a new for each loop so it is processed after the dir is created and tested? If so how do you arrange the { } parts?

Edit 2 I finally have it working, updated script below, the movie-item command was having issues when running into special characters in file names, in my case it was square brackets. The -literalpath switch fixed that for me. Thanks every one for your input.

Updated script 3.0

#Set source folder
$source = "D:\test\source\"
#Set destination folder (up one level of true destination)
$dest = "D:\test\dest\"
#Define filter Arguments
$filter = "*.txt"
<#
$sourcefile - finds all files that match the filter in the source folder
$trimpath - leaves $file as is, but gets just the file name.
$string - gets file name from $trimpath and converts to a string
$trimmedstring - Takes string from $trimfile and removes the last 16 char off the end of the string
Test for path, if it exists then move on, If not then create directory
Move file to new destination
#>
pushd $source
$sourcefile = Get-ChildItem $source -Filter $filter
foreach ($file in $sourcefile){
$trimpath = $file | split-path -leaf
$string = $trimpath.Substring(0)
$trimmedstring = $string.Substring(0,$string.Length-16)
If(!(Test-Path -path "$dest\$trimmedstring")){New-Item "$dest\$trimmedstring" -Type directory -Force}        
move-Item -literalpath "$file" "$dest\$trimmedstring"
}

Solution

  • I finally have it working, updated script below, the movie-item command was having issues when running into special characters in file names, in my case it was square brackets. The -literalpath switch fixed that for me. Thanks every one for your input.

    #Set source folder
    $source = "D:\test\source\"
    #Set destination folder (up one level of true destination)
    $dest = "D:\test\dest\"
    #Define filter Arguments
    $filter = "*.txt"
    <#
    $sourcefile - finds all files that match the filter in the source folder
    $trimpath - leaves $file as is, but gets just the file name.
    $string - gets file name from $trimpath and converts to a string
    $trimmedstring - Takes string from $trimfile and removes the last 16 char off the end of the string
    Test for path, if it exists then move on, If not then create directory
    Move file to new destination
    #>
    pushd $source
    $sourcefile = Get-ChildItem $source -Filter $filter
    foreach ($file in $sourcefile){
    $trimpath = $file | split-path -leaf
    $string = $trimpath.Substring(0)
    $trimmedstring = $string.Substring(0,$string.Length-16)
    If(!(Test-Path -path "$dest\$trimmedstring")){New-Item "$dest\$trimmedstring" -Type directory -Force}        
    move-Item -literalpath "$file" "$dest\$trimmedstring"
    }