1

I have the following problem and I would really appreciate it if I could get some help on that front. I am getting a constant flow of xml files into a folder. A XML file name can look like this. It only goes up to 1005.

1001.order-asdf1234.xml
1002.order-asdf4321.xml

I want to sort the files into uniquely named folders that are not based on the file names. A example for that would be

C:\Directory Path...\Peter (All files starting with 1001 go in there)
C:\Directory Path...\John (All files starting with 1002 go there)

How can I create a batch or a powershell script to continuously sorts files into the specified folders? Since I only have 5 folders I would like to simply specify the target folders for each and not have elaborate loops but I don't know how to do that.

1

2 Answers 2

2

The easiest way is to create a lookup Hashtable where you define which prefix ('1001' .. '1005') maps to which destination folder:

# create a Hasthable to map the digits to a foldername
$folderMap = @{
    '1001' = 'Peter'
    '1002' = 'John'
    '1003' = 'Lucretia'
    '1004' = 'Matilda'
    '1005' = 'Henry'
}

# set source and destination paths
$rootFolder = 'X:\Where\the\files\are'
$destination = 'Y:\Where\the\files\should\go'

# loop over the files in the root path
Get-ChildItem -Path $rootFolder -Filter '*.xml' -File | 
Where-Object { $_.BaseName -match '^\d{4}\.' } | 
ForEach-Object {
    $prefix = ($_.Name -split '\.')[0]
    $targetPath = Join-Path -Path $destination -ChildPath $folderMap[$prefix]
    $_ | Move-Item -Destination $targetPath -WhatIf
}

Remove the -WhatIf safety-switch if you are satisfied with the results shown on screen

Sign up to request clarification or add additional context in comments.

Comments

1

You could use a switch statement to decide on the target folder based on the first part of the file name:

$files = Get-ChildItem path\to\folder\with\xml\files -Filter *.xml
switch($files)
{
  {$_.Name -like '1001*'} {
    $_ |Move-Item -Destination 'C:\path\to\Peter'
  }

  {$_.Name -like '1002*'} {
    $_ |Move-Item -Destination 'C:\path\to\John'
  }

  {$_.Name -like '1003*'} {
    # etc...
  }

  default {
    Write-Warning "No matching destination folder for file '$($_.Name)'"
  }
}

If you change your mind about loops, my preference would be to store the mapping in a hashtable and loop over the entries for each file:

$files = Get-ChildItem path\to\folder\with\xml\files -Filter *.xml

$targetFolders = @{
  '1001' = 'C:\path\to\Peter'
  '1002' = 'C:\path\to\John'
  '1003' = 'C:\path\to\Paul'
  '1004' = 'C:\path\to\George'
  '1005' = 'C:\path\to\Ringo'
}

foreach($file in $files){
  $targetFolder = $targetFolders.Keys.Where({$file.Name -like "${_}*"}, 'First')

  $file |Move-Item -Destination $targetFolder
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.