0

I'm trying to take files in existing sub-directories and create new directories, each containing six files within their current subdirectory. This is for use with a batch analysis tool that can only currently handle six files reliably and can only open directories. My code iterated through each subdirectory and created the appropriate number of new directories but didn't move any of the files.

Get-ChildItem -Directory | ForEach-Object {
    $directory_count = 0;
    $files = Get-ChildItem $_ -filter *.xml;
    $curr_dir = $_;    
    $i = 0;
    Write-Host "Working on $_.FullName"
    foreach ($file in $files) {
        if ($i -eq 6) {
            $directory_count += 1;
            $i = 0;
        }
        if (Test-Path ".\$curr_dir\$directory_count") {
        }
        else {
            New-Item -ItemType Directory -Force -Path ".\$curr_dir\$directory_count";
        }
        Move-Item -Path $curr_file -Destination ".\$curr_dir\$directory_count";
        $i += 1;
    }
}
  • Chris, you're assigning an Object to $curr_dir. You then try to use it in -Path arguments where Text is required. This will not work. You need to get the FullName property of the directory object and construct your path from there for the new directories. You'll most likely also have to strip off the drive designeation, e.g. C: – RetiredGeek Aug 14 '23 at 21:58
  • Change `Move-Item -Path $curr_file ...` to `$file |Move-Item ...` – Mathias R. Jessen Aug 15 '23 at 11:11

1 Answers1

0

Converts from

\
  testmp-1.txt
  testmp-2.txt
  testmp-3.txt
  testmp-4.txt
  testmp-5.txt
  testmp-6.txt

To

+---dir-1
¦       testmp-1.txt
¦       testmp-4.txt
¦       
+---dir-2
¦       testmp-2.txt
¦       testmp-5.txt
¦       
L---dir-3
        testmp-3.txt
        testmp-6.txt

#settings
$root = [System.IO.Path]::Combine([System.IO.Path]::GetTempPath(), [Guid]::NewGuid())
$dirCount = 3

#Emulator Create
[void][System.IO.Directory]::CreateDirectory($root)
@(1..6) | % { [System.IO.File]::WriteAllText([System.IO.Path]::Combine($root, "testmp-$_" + '.txt'), $_)  }

#Demonstrate
&tree /F "$root"
    
#Create dirs and get their full names
$targetDirList = @(@(1..$dirCount) | 
    ForEach-Object {[System.IO.Path]::Combine($root, "dir-" + $_.ToString())} |
    ForEach-Object {[System.IO.Directory]::CreateDirectory($_)} |
    Select -ExpandProperty FullName)

#Sort files from $root to $targetDirList, each file comes to next dir in $targetDirList
$targetDirId = 0;
[System.IO.Directory]::EnumerateFiles($root, '*', [System.IO.SearchOption]::TopDirectoryOnly) | 
    ForEach-Object {
        [System.IO.File]::Move($_,
            [System.IO.Path]::Combine(
                $targetDirList[$targetDirId],
                [System.IO.Path]::GetFileName($_)))
        $targetDirId = ($targetDirId + 1) % $targetDirList.Length # Next targetDirId
    }

#Demonstrate
&tree /F "$root"

#Emulator Delete
[System.IO.Directory]::Delete($root, <#Recursive#> $true)
filimonic
  • 3,988
  • 2
  • 19
  • 26