Renaming

In my ongoing struggles with renaming scripts, I’ve had occasion to come across duplicate file names. I’d like to just rename the file with the more recent date, while leaving the other alone.

Is there a punchy way to do this without a lot of acrobatics and/or saves memor? I think I’ve been approaching it in a way that really bogs things down by using counters. Yikes.

Hi,
I’m not entirely sure on your scenario, when you say you have duplicate file names I’m presuming you’re trying to move a file into a directory that already has a file with the same name??? maybe something like this example would help!

set file1 to choose file
set file2 to choose file

set file1_info to {filename:name, mod_date:modification date} of (info for file1)
set file2_info to {filename:name, mod_date:modification date} of (info for file2)

tell application "Finder"
	if filename of file1_info = filename of file2_info then
		if mod_date of file1_info > mod_date of file2_info then
			set new_name to text 1 thru -5 of (filename of file1_info) & "_latest" & text -1 thru -4 of (filename of file1_info)
			set name of file1 to new_name
		else if mod_date of file2_info > mod_date of file1_info then
			set new_name to text 1 thru -5 of (filename of file2_info) & "_latest" & text -1 thru -4 of (filename of file2_info)
			set name of file2 to new_name
		end if
	end if
end tell

Thanks,
Nik

Sorry I was vague about things. I think the script you posted is a good direction - and certainly beneficial for anyone in the scenario as you interpreted it - but my user needs to have more of the legwork performed by the script.

Basically, I have a script (below) that renames files in a large directory based on a delimited tabbed text file. One column has the old name, the other contains the corresponding new name. That seems to work swimmingly, with the able advice of my fellow posters.

After examining the contents of the directory in which I’m renaming, I’ve realized there are duplicate instances of the same filename. For example, aaa.psd will appear in one subfolder and then aaa.psd will appear again at some subfolder. The original script does a try, posts an error that it can’t rename more than one file of the same name and moves on.

What I’m now trying to do is accommodate those duplicates. Whenever it has multiple file names with the same string of characters, it should rename the newest one (by date modified) and delete the rest. I found a very helpful post by user “kel” for a script that does just that - but my script gets hung up. It can’t seem to sort the contents of the directory by name - it tells me the handler can’t handle a class at:

set file_refs to (sort file_refs by name)

There may be other minor defects downstream because of my not knowing how to fix this. It seems like a great script - and one that is very nearly finished - but I’m in need of a coder better than I to give it a look.

I apologize to post such bloated code, but the part in question is really just the section of code (and subroutine it refers to) that attempts to sort all the file names, find the duplicates and delete.

Thanks so much for your responses and insight.


-- DECLARE PROPERTIES

--basic file path and names
property g_home_folder_path : (path to desktop)
property g_log_file_name : "Failed_to_Rename.txt"

set sourceFolder to (choose folder) as text

set textFile to (choose file of type "TEXT") as text

-- get rid of duplicates by modification date
set file_refs to MakeFileList(sourceFolder)
set num_items to count file_refs

if num_items > 1 then
	tell application "Finder"
		set file_refs to (sort file_refs by name)
		repeat with i from 2 to num_items
			set j to i - 1
			
			set ref_i to item i of file_refs
			set ref_j to item j of file_refs
			
			set name_i to name of ref_i
			set name_j to name of ref_j
			
			if name_i is name_j then
				set mod_date_i to modification date of ref_i
				set mod_date_j to modification date of ref_j
			else
				if mod_date_i > mod_date_j then
					delete ref_j
				else
					delete ref_i
					
				end if
			end if
			
		end repeat
	end tell
end if


-- read in the list of names
set filenameList to paragraphs of (read file textFile)

-- in order to break out the two fields 
-- with text item delimiters
set {oldDelims, text item delimiters} to {text item delimiters, tab}

set err to 0
set allFiles to count filenameList
repeat with aFile in filenameList
	
	
	set {codified_name, real_name} to text items of aFile
	set foundFile to do shell script "/usr/bin/find " & quoted form of POSIX path of sourceFolder & " -name " & quoted form of codified_name
	
	if foundFile is "" then
		set err to err + 1
		my logMe(codified_name as text, 0)
		
	else
		try
			tell application "Finder" to set name of (POSIX file foundFile as alias) to real_name
		on error m number n
			my logMe("RENAME FAILED: " & foundFile & " (" & codified_name & ") to " & real_name & "; error " & n & ": " & m, 1)
			--error m number n -- reissue the error; uncomment this line to make the script abort on an error here
		end try
	end if
end repeat

set text item delimiters to oldDelims
set msg to (allFiles as text) & " files processed"
if err > 0 then set msg to return & (msg & err as text) & " files not found"
display dialog msg



--Log Entry Generation

on logMe(log_string, indent_level)
	set log_target to g_home_folder_path & g_log_file_name as text
	try
		set log_file_ref to open for access file log_target with write permission
		repeat indent_level times
			write tab to log_file_ref starting at eof
		end repeat
		write ((log_string as text) & return) to log_file_ref starting at eof
		close access log_file_ref
		return true
	on error
		try
			close access file log_target
		end try
		return false
	end try
	
end logMe

-- Makes List of Files in Directory

on MakeFileList(sourceFolder)
	
	set {saveDelims, text item delimiters} to {text item delimiters, ASCII character (13)}
	set lst to list folder sourceFolder without invisibles
	set i to do shell script "echo " & lst & "|sort"
	set sortedList to text items of i
	set text item delimiters to saveDelims
	
	-- end try
	
	return saveDelims
end MakeFileList

Hi,
just wanted to check I’ve got this correct before I go down the wrong track. The script searches a large directory that also contains sub directories for files that have the same name as the text that resides in the old column name, if it finds a match then it will rename that file to the new name given in the second column of the text file. The problem being that it could rename a file in a sub directory the same as a file that resides in another directory, but you need to know which one has the most recent modified date and delete the older ones.
Can you confirm that I’ve got this correct.
Thanks,
Nik

Hey,

Thanks for responding! Sounds exactly right to me. The script has no problem finding and pathing the files in the first column, then giving them the new name from the second column.

It runs into problems is when the same filename appears twice in the directory - which naturally is possible when the directory contains more than one level.

My desire is to rename the newest file and delete the other files with the same name, like you say. My above script is my most recent attempt to achieve this. I’m not sure if the error I mentioned is the offending one, but the code I inserted to handle this issue was adapted from another post on here that was successful.

Just doesn’t want to work with my script for some reason.

Thanks for asking for clarification too - hope that helps. You were pretty much dead on.

Hi,
I believe the the error is occurring when the result of the shell find returns more than one result. Please give the code below a try, change the codified_name and real_name variables to suit filenames in your text file and then place a few files with the same name in different sub directories of your master directory but with different modification dates. I have put descriptions in the script to explain what the scripts doing.
Thanks,
Nik

set sourceFolder to choose folder
set codified_name to "nik*"
set real_name to "I love Applescript"

set foundFile to do shell script "/usr/bin/find " & quoted form of POSIX path of sourceFolder & " -name " & quoted form of codified_name --> this will return every file in the master directory and sub directories that have the same name as the codified_name variable

set count_of_foundFile to count of paragraphs of foundFile

if count_of_foundFile > 1 then
	set file_list to {}
	repeat with i from 1 to the count of paragraphs of foundFile --> if there is more than one file with the same name then make a list the,
		set this_file to (POSIX file (paragraph i of foundFile))
		copy this_file to end of file_list
	end repeat
	tell application "Finder"
		set SortedFiles to sort file_list by modification date --> sort the list of files with the same name by modification date
		set most_recent_file to item 1 of SortedFiles
		set name of most_recent_file to real_name --> rename the most recent file
		delete items 2 thru end of SortedFiles --> delete the rest
	end tell
else if count_of_foundFile = 1 then
	tell application "Finder" to set name of (POSIX file foundFile as alias) to real_name --> if there's only 1 file with the codified_name name then rename it
end if