1

So I apparently have hundreds of "albums" in my music folder with only one music file in it.

I don't like that, I want only complete albums in that folder.

Is there an easy solution to this? In essence a tool that deletes all folders with only one file in it? I'm using Windows 7

2
  • Which OS are you using?
    – Karan
    May 20, 2013 at 18:28
  • Sorry for not mentioning that. See the edit
    – Forza
    May 20, 2013 at 18:29

2 Answers 2

1

Open up PowerShell ISE and try running this:

$targets = @()
$folders = dir "D:\Users\Forza\Music\" | Where {$_.mode -match "d"}
foreach ($folder in $folders) {
     if(
        ($folder.GetFiles() |
         Measure-Object |
         Select -ExpandProperty Count) -eq 1) 
        {$targets += $folder}
}
$targets | Format-Table -Property Name

This (should) kick out a list of all folders with a single file in them. Take a good look at the list and make sure there's no unintended folders. Then you can run the command:

foreach ($target in $targets){Remove-Item -Recurse -Force $target.FullName}

This will delete all the folders that were listed in $targets.

If you need to modify this script, it helps to understand what it's doing. For example, as-is you would be deleting any folders with subfolders but no files in the first directory. So if you have something like C:\Users\Forza\Music\SomeArtist\SomeAlbum, the entire directory SomeArtist would be deleted. Also, any empty folders will remain.

Let's go line-by-line:

  1. $targets = @() defines an array. This is so we can add $folders to $targets without throwing an error and make sure that $targets starts out empty, rather than continually adding to it while modifying our script and eventually deleting far more folders than we intended.
  2. $folders = dir 'C:\Users\Forza\Music\' | Where {$_.mode -match "d"} lists the contents of the specified directory and pipes that output to the Where-Object command. $_.mode -match "d" takes the piped objects and checks that they are directories.
  3. foreach ($folder in $folders) { start looping through each folder
  4. if( begins an if statement to check file count inside the folder. I've split each line to make it confusing readable.
  5. $folder.GetFiles() | this grabs all the files in the folder we're checking. Notice the pipe, which sends the output to the next command on the next line.
  6. Measure-Object | is pretty self explanatory. If not, try the command Get-Help Measure-Object.
  7. Select -ExpandProperty Count) -eq 1) selects and expands the Count property so we can see if it equals (-eq) 1. Notice the two closing parenthesis, one to close ($folder.GetFiles() | Measure-Object | Select -ExpandProperty Count) and one to close the if statement.
  8. {$targets += $folder} adds our criteria-matching folder to our $targets list.
  9. } closes the foreach loop.
  10. $targets | Format-Table -Property Name kicks out the list of folders for deletion.

If you wanted to modify this to delete empty folders as well, simply change -eq 1 to -lt 2. With a little creativity you should be able to get the script to handle your messy file structure however you see fit.


To take care of an Artists folder under \Music, change the path to something like C:\Users\Forza\Music\*\*\.

6
  • 1
    You could just do it initially with the Remove-Item in place but give it the -WhatIf parameter. Then remove the -WhatIf to do it for real.
    – EBGreen
    May 20, 2013 at 19:25
  • What a great idea to do this in powershell :) Very cool! However, it lists folders with full albums in it.. Can you make sure this code does what it intents to do?
    – Forza
    May 20, 2013 at 19:30
  • EBGreen's solution does not create a list. It asks me per folder if I like to delete them. I can't hit apply to all as it will remove folders which have sub-folders with multiple files inside them. I will have to go trough every folder to select yes or no for deleting them. For yours, I am not sure what it's doing. Check this: piclair.com/data/q8g34.jpg The top Jack Johnson folder contains 12 albums, whereas 1 has only one mp3 in it. I am not sure whether your script will remove the entire jack johnson folder, or only that corrupt one inside it. Can you please explain a bit more?
    – Forza
    May 20, 2013 at 21:35
  • You can assume that there's always a folder for the artist which contains the albums.
    – Forza
    May 20, 2013 at 21:52
  • @Forza Tried to add the path change in a comment but Markdown won the battle. I think this should work for EBGreen's much cleaner one-line solution as well.
    – rtf
    May 20, 2013 at 22:21
1

This did it for me:

ls I:\temp | ?{$_.PSIsContainer} | ?{(ls $_.FullName | ?{-NOT $_.PSIsContainer}).Count -eq 1} | %{Remove-Item $_.FullName -WhatIf}

Remove the -WhatIf to do it for real. Note that it will remove a folder that has one file in it even if it has sub-folders with more files.

4
  • Well, that is a downside. Now I will have to go trough hundreds of folders to select yes or no :(
    – Forza
    May 20, 2013 at 21:30
  • So you don't want it to delete folders that have sub folders? You want it to delete only subfolders with one file? Delete the entire tree if there is only one folder anywhere in it? Computers are very literal animals. If you don't give them very specific instructions, you usually won't get the result that you expected.
    – EBGreen
    May 20, 2013 at 22:18
  • Yes. From my main music folder, I want to delete all artist folders, that have one album with one file in it. Nothing more :)
    – Forza
    May 21, 2013 at 9:07
  • So if it was a folder with one file in it and a completely empty sub-folder, you would not want to delete it?
    – EBGreen
    May 21, 2013 at 13:32

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .