Check if file already exists and create a new file with name and appended number


I have the following scenario that I’m trying to script:

  • Copy files into 1 directory from a set of txt files in another nested directory structure
  • File test.txt is copied to C:\test from a nested directory structure
  • test.txt is copied from a 2nd nested directory structure to C:\test but test.txt already exists
  • Before the 2nd test.txt is created, generate a new file name of test_1.txt and then copy to this file.
  • Another test.txt from a 3rd nested directory structure is copied to C:\test but test.txt exists and test_1.txt exists. Generate a new file name test_2.txt and then copy to this file.
This is the code I have but it's using loops, I would like to do this without loops - is it possible?
$newpath = $path + "\" + $filename + $ext
$newname = $filename
$counter = 0
	while (Test-Path($newpath)) {
		$newname = $filename + "_" + $counter + $ext
		$newpath = $path + "\" + $newname

$thenewfilename = $newname

No, not with pure Powershell. What’s wrong with loops?

Or actually it would be possible without a loop but it would not be shorter … :wink:

Trying to cut the speed down by using efficient code. Bit concerned if I get a 10000 txt files. I was thinking if there’s a way other than a while loop?

10000 … ok … you could try to “determine” the next $counter with another method. You could name the files with a certain pattern like “test_00001.txt”, “test_00002.txt” and so on. When you do a Get-ChildItem -Filter “test_*.txt” and pipe it to Sort-Object and take the last one you just have to increase it’s counter by one and your done. :wink:

Unfortunately, not all files have a structure to make them uniform enough. Hence my example, text.txt in multiple nested directories.

OK, but you need to specify the file name for your task anyway!? You have a counter and you have a perticular file name, right? Or did I get something wrong?

A possible alternative approach. Rather than testing each file name and increment of that file name using test-path, you could:

  1. Get-ChildItem for that $filename*.txt in the target directory
  2. See if any results retuned:
    1. If not copy file to target directory and move to on
  3. If files found that begin with the name, sort and get the last character of the last file and increment it for the new name of the new file
You might have issues with this method if file names have partial matches with other filenames IE file.txt and filename.txt, so you might also want to add a where statement so that it begins with your $filename followed only by your possible addon-tab. IE underscore and a number.

Just a thought