Share via


PowerShell to delete all files but 1 in a dir?

Question

Thursday, June 1, 2017 1:45 PM

I'm trying to delete all but one .txt files in each folder of a directory tree. The number of the .txt files varies in each subdirectory, and so do the names. Some subdirectories have five .txt files in them, and some have only one. If the folder has only one .txt file, it needs to stay there. I the folder has more than one .txt file in it, then all others but one need to be deleted. It doesn't matter which .txt file is kept. I just need the rest to be deleted. I've tried various versions of "get-content" or "get-childitem" or "measure-object", but I'm not having any luck.  Anyone smarter than me have an idea how to approach this? Thank you.

All replies (8)

Friday, June 2, 2017 6:51 AM ✅Answered

To build on what the others has already said, what you need to do:

Get the folders that you want to clear the files in

Loop through them and remove all but one file

Should look something like this (I tried it and it worked):

$folders = Get-ChildItem c:\temp\test -Recurse -Directory
foreach($folder in $folders.fullname){
    Write-Host "Clearing in $folder"
    Get-ChildItem -Path $folder -Filter '*.txt' | Select-Object -Skip 1 | Remove-Item
}

Thursday, June 1, 2017 1:53 PM

Hello,

let's say: This is quite simple. You'll only need Remove-Item cmdlet and use it like this

Remove-Item "Path\*"

to delete all files in <Path>. To exclude files from this selection, use parameter -Exclude. But of course, you need a definition how this file looks like.

I don't see any reason for using Measure-Object here. I think, you should learn some Powershell basics first. 

Good luck

Christoph


Thursday, June 1, 2017 2:37 PM

Thanks for your reply. Your example will simply remove all files. I need to leave one file in each dir, and if there is only one file in a dir, then it needs to stay there. Perhaps I didn't make that clear. Sorry about that.

I was playing with Measure-Object to count files, like the following: Get-ChildItem -Path f:\temp -Recurse -File | Measure-Object | %{$_.Count}. I thought that may be step 1: count the files.


Thursday, June 1, 2017 2:59 PM | 1 vote

Get-ChildItem -Filter '*.txt' | Select-Object -Skip -First 1 | Remove-Item

Grüße - Best regards

PS:> (79,108,97,102|%{[char]$_})-join''


Thursday, June 1, 2017 3:17 PM

Thank you, I really appreciate the attempt, but that doesn't work either.


Thursday, June 1, 2017 3:25 PM

Get-ChildItem -Path "C:\Temp\\ -Filter '*.txt' -Recurse | Select-Object -Skip 1 | Remove-Item

The above will work for the first directory it sees. All other directories have all .txt files removed, however. I'm trying to leave behind one .txt file in each directory. 


Thursday, June 1, 2017 3:49 PM | 1 vote

So you should collect first all directories you wish to treat and then run this command foreach collected directory but without the -recurse parameter.

Grüße - Best regards

PS:> (79,108,97,102|%{[char]$_})-join''


Friday, June 2, 2017 1:55 PM

That's a prettier solution than what I came up with, and it works perfectly. Thank you!