Move files without overwriting.

I am trying to write a very simple folder action script that will move created PDFs from Distiller’s ‘Out’ folder on the server to a folder that is accessible by all users. The trouble is I’m a complete newb and I can’t get the script to behave exactly as I would like. This is what I have so far:

on adding folder items to this_folder after receiving added_items
	tell application "Finder"
		move (files in folder this_folder whose name extension is "PDF") to folder "ExampleDisk:ExampleFolder:PDFs" replacing yes
	end tell
end adding folder items to

This works well so far except for one ‘problem’ - if a user sends the same file a second time (eg an alternate version) the first version is overwritten. This is completely normal since I have ‘replacing yes’ at the end of the move command, the problem is if I use ‘replacing no’ or nothing at all my files don’t get moved at all - if there is a file with the same name in the destination folder they just stay in the ‘Out’ folder.

Is there a way to tell the ‘move’ command that if a file already exists to automatically append ‘-1’, ‘-2’ etc to the end of the filename? It doesn’t have to be a ‘move’ command, it could be ‘copy’ or ‘duplicate’ etc since I have already set up a cron script to periodically empty the involved folders.

Thanks

Si

You could use a repeat loop (that repeats as many times as the number of files added) to add something to the file name.

tell application “Finder”
set fileList to name of every file of (your destination) as list
repeat with i from 1 to countOfItems (count of items is either done before or after adding items depending on how you write the script.)
select file i of (file path)
set fileName to name of selection
if fileList contains fileName then
set fileName to fileName & i (where i is the number from the loop.)

You could also put in a display dialog where text would be entered and appended to the name such as: display dialog “Add text to file name.” default answer “” (next line) set txt to text returned of the result (next line) set fileName to fileName & txt

move file fileName of (file path to your file) to (your destination)
end repeat
end tell

Someone else probably has a better way to do this but this is what I came up with. Hope it helps.

I know this was not meant to be actual code, but more of a guide. You start running into trouble doing this kind of loop for the following reasons:

If you check only the current added_items names against the destinationFolder_names, you may rename to a file already in added_items, and produce and error.

added_items destinationFolder_names
1.pdf 2.pdf
2.pdf 6.pdf
3.pdf 7.pdf

renames 2.pdf to 3.pdf in the same folder, and produces an error

If you run an auto “set fileName to fileName & i (where i is the number from the loop” you may rename to a different file in destinationFolder_names. ie:
added_items destinationFolder_names
1.pdf 3.pdf
2.pdf 4.pdf
3.pdf 5.pdf

renames 3.pdf to 4.pdf and cannot move due to error, etc.

You could create code to deal with these conditions, but there is a simpler way to keep your files moving without trying to order them sequentially. Run an initial filename check between added_items and destinationFolder_names. If two filenames match, rename the added_item to the name and your version of the date stamp. Append the filename with month_day or month_day_year and that should keep any filename conflicts from happening.


--on adding folder items to ThisFolder after receiving added_items

set ThisFolder to choose folder --example of attached folder
set DestinationFolder to choose folder --you can hardwire this path if the destination is constant

tell application "Finder" to set added_items to every file of ThisFolder

tell application "Finder" to set added_items_FilenameList to name of every file of added_items as list

tell application "Finder" to set ExistingFilenames to name of every file of DestinationFolder as list


repeat with ThisFile in added_items
	set ThisFilesName to name of ThisFile as string
	if ThisFilesName is in ExistingFilenames then
		
		set AppleScript's text item delimiters to "."
		set BaseFilename to text item 1 of ThisFilesName
		set FileExt to name extension of ThisFile
		set AppleScript's text item delimiters to ""
		
		set DateStamp to do shell script "date +%m_%d_%y"--You may want to remove '_%y' 
		
		set name of ThisFile to BaseFilename & "_" & DateStamp & "." & FileExt
		
	end if
end repeat

tell application "Finder" to set Renamed_added_items to every file of ThisFolder
tell application "Finder" to move Renamed_added_items to DestinationFolder


You can run this as is in a Script Editor window or adapt it to a folder action.

SC

One final note: if multiple files are added in a day of the same name, you would start to get errors. In this case, you could add a time stamp as well.
Example.pdf → Example_63_915a.pdf
would be 6/03 at 9:15 am, etc.

Here’s one way of doing it:

property tgtFolder : alias "ExampleDisk:ExampleFolder:PDFs"
property suffX : ".pdf"

on uniqueName for currName against nameList
	if currName is not in nameList then return currName
	set baseName to currName's text 1 thru -((count suffX) + 1)
	set n to 1
	set testName to baseName & "-" & n & suffX
	repeat while testName is in nameList
		set n to n + 1
		set testName to baseName & "-" & n & suffX
	end repeat
	testName
end uniqueName

on adding folder items to this_folder after receiving added_items
	tell application "Finder"
		set nameList to name of tgtFolder's files
		repeat with currItem in added_items
			set currName to currItem's name
			if currName ends with suffX then
				set newName to my (uniqueName for currName against nameList)
				set nameList's end to newName
				if currName is newName then
					move currItem to tgtFolder
				else
					set currItem's name to " "
					move currItem to tgtFolder
					set currItem's name to newName
				end if
			end if
		end repeat
	end tell
end adding folder items to

I tried to move this folder of test files with the above code to a folder with identical filenames:

Dogman.pdf
suger_03_02_06_05.pdf
suger_03.pdf
suger_02_06_05.pdf
suger_02_02_06_05.pdf
suger_02.pdf
suger_01_02_06_05.pdf
suger_01.pdf
suger.pdf
newinformation_02_06_05.pdf
newinformation.pdf

and produced the error: Can’t complete move, name exists already. Then it renamed

Dogman.pdf to “”
and highlighted the code

set currItem’s name to " "

Its tricky when you start considering all the different cases you might run into. I would still like to see it done, I just think it’s going to take some math.
SC

There must be a sipler solution then all this jazz.

The simplicity is lost in the fact that there is no “standard” kept in naming files. There are characters you can’t use, but beyond that, they can get ugly. If we knew the filenames that were being generated in the outfolder, we could create a uniform standard. Otherwise you’re left to error check case by case. siMac can see those filenames and knows what they look like, so if we could get some examples…
SC

Weird. :confused:

I obviously tested the script here before posting, and it worked perfectly. I’ve now run further tests using the filenames above - and even repeated the process 10 times (with exactly the same filenames again). My target folder now contains a total of 121 files from the original 11 - all perfectly renamed, and without a trace of a hiccup.

Must be some other issue involved…

We’re open to any suggestions… :wink:

Thanks kai, I’ll give your script a try first thing monday. I still can’t believe how much botching is required for a relatively simple outcome! :stuck_out_tongue:

I just want behavior similar that of Safari when you download the same file twice to the same location: ‘download.file’, ‘download.1.file’ and so on…

Thanks to all for the help so far!

Botching? Botching??? :wink:

Kai your script works like a charm! Exactly what I was looking for - you truly are a world class botcher! :smiley:

Thanks a million…

Thanks, siMac… (I think). :wink:

No problemo.

Indeed kai, your script works perfectly with one file type and thank you for it! :slight_smile: I’m trying to make an all-in-one image collecting script and was wondering how to modify it to work with multiple file extensions? IE: png, gif, jpg, etc. I’ve tried changing suffX to

property suffX : {".jpg", ".gif", ".png"}

and it compiles fine, but it doesn’t work. Any help anyone could give would be extremely appreciated. I’m afraid I’m a bit (understatement) of an Applescript newbie. :wink:

John - please accept my apologies for the tardy response.

I somehow missed your question here - and only just realised today that you’d left me a personal message, too. (Oops! :rolleyes:)

I’ve revised the original script to accommodate a list of filename extensions - which can be modified as required. Please let me know if you need any more help.

property tgtFolder : alias "path:to:target folder:" (* modify as necessary *)
property Xlist : {"jpg", "gif", "png"}

on uniqueName for currName thru currExtn against nameList
	if currName is not in nameList then return currName
	set baseName to currName's text 1 thru -((count currExtn) + 1)
	set n to 1
	set testName to baseName & "-" & n & currExtn
	repeat while testName is in nameList
		set n to n + 1
		set testName to baseName & "-" & n & currExtn
	end repeat
	testName
end uniqueName

on adding folder items to this_folder after receiving added_items
	tell application "Finder"
		set nameList to name of tgtFolder's files
		repeat with currItem in added_items
			set currName to currItem's name
			set currExtn to currItem's name extension
			if currExtn is in Xlist then
				set newName to my (uniqueName for currName thru "." & currExtn against nameList)
				set nameList's end to newName
				if currName is newName then
					move currItem to tgtFolder
				else
					set currItem's name to " "
					move currItem to tgtFolder
					set currItem's name to newName
				end if
			end if
		end repeat
	end tell
end adding folder items to

Edit: Ah - I’ve just noticed that a new thread was started here. No matter - as long as you have the answer you need… :slight_smile:

Hiya kai,

What a helpful forum this is. Try to imagine being apologized to, by a moderator no less, because they think they were tardy in helping you! :lol: Obviously, there’s no need for you to apologize my friend. When I didn’t get a response here after 10+ days I simply made a new thread and was quickly helped there. You (and Jacques) have been nothing but incredibly helpful and friendly. Please accept my apology for “spamming” the forums for the same topic in two places. Again, thank you for all your help and never apologize to people for helping them, it’s never needed. :wink: