Powershell - Create a folder from a file name, then place that file in the folder

17.2k Views Asked by At

I have a list of files say...

T123_Product_1.jpg
T123_Product_2.jpg
T123_Product_3.jpg
T456_Product_1.jpg
T456_Product_2.jpg
T456_Product_3.jpg 

etc. etc. etc. for about 900 more files

What I am needing to do is create a folder based on the characters before the first underscore, but to not repeat it since there are multiple files.

So in the example above, I would only want two folders named T123 and T456.

Then I would need the script to place the appropriate files in the folder.

I had found some codes in this thread, but they don't exactly do what I'm looking for.

https://superuser.com/questions/306890/windows-batch-script-to-create-folder-for-each-file-in-a-directory-name-it-tha

    $Files = Get-ChildItem -Path 'C:\Info\AUGUST 2011\Checklists\' -Filter 'DET1__*'
$Files | ForEach-Object {
    $FileFullName = $_.FullName
    $TempFileName = "$($FileFullName).tmp"
    $DestinationFileName = "$FileFullName\$($_.Name)"
    Move-Item $FileFullName $TempFileName
    New-Item -Path $FileFullName -ItemType Directory
    Move-Item $TempFileName $DestinationFileName
}

Any help?

3

There are 3 best solutions below

0
On BEST ANSWER

The easiest way here would be to group the files by the first part, which will then become the directory name. In typical PowerShell pipeline manner this is fairly succinct:

Get-ChildItem -File |  # Get files
  Group-Object { $_.Name -replace '_.*' } |  # Group by part before first underscore
  ForEach-Object {
    # Create directory
    $dir = New-Item -Type Directory -Name $_.Name
    # Move files there
    $_.Group | Move-Item -Destination $dir
  }
0
On
$directory="c:\temp\"

#explicit and long version
Get-ChildItem -File -Path $directory -Filter "*.jpg" | 
ForEach-Object {
New-Item -ItemType Directory "$directory$($_.Name.Split("_")[0])" -Force;   
Move-Item -Path $_.FullName -Destination  "$directory$($_.Name.Split("_")[0])\$($_.Name)"      
}

#short version 
gci -File -Path $directory -Fi "*.jpg" | 
%{ ni -ItemType Directory "$directory$($_.Name.Split("_")[0])" -Force;mvi $_.FullName "$directory$($_.Name.Split("_")[0])\$($_.Name)" }
0
On

Also try.

cd <path to your folder>
  $files = Get-ChildItem -file;
  ForEach ($file in $files)
  {
    $folder = New-Item -type directory -name ($file.BaseName -replace "_.*");
    Move-Item $file.FullName $folder.FullName;
  }

You can use the Substring method on the $file.BaseName as well.

cd <path to your folder>
$files = Get-ChildItem -file;
ForEach ($file in $files)
{
  $fileName = $file.BaseName;
  $folder = New-Item -type directory -name $fileName.Substring(0, $fileName.Length-10);
  Move-Item $file.FullName $folder.FullName;
}

The same posted here with explanation.