deleting hidden ._ files

Hi, everyone

I am quite green when it comes to AppleScript, but not scripting and programming as such. So AppleScripts syntax is a bit confusing to me.

I want to make a droplet that removes all files that start with ._ on drives and folders. These files ar such a pain when moving things to PC drives. :slight_smile:

I started with Apples droplet examples as a blueprint since they do pretty much all I want. The example can be found here:
http://www.apple.com/applescript/guidebook/sbrt/pgs/sbrt.09.htm

I used the second one (nested folders example). I have two questions about this example and the way it works.

  1. The alias that is passed to “process_item” does not take “delete (the original of this_item)” as a statement. It can not access the original of the alias. I have tried using different syntaxes and versons but no luck. What is passed here? And how do I write something that can alter the file is is refering to?

I first worked around this by using:
set myfile to the quoted form of the POSIX path of this_item
do shell script "rm -f " & myfile
but then comes problem number 2…

  1. This is even worse for me. The script can not find the hidden ._ files I want to delete. I have altered the following:

from: the name extension of the item_info is in the extension_list )then
to: the name of the item_info starts with “._”) then
in both places in the script.

from: set these_items to list folder this_folder without invisibles
to: set these_items to list folder this_folder with invisibles

Searching for files that start with “test” or similar works. I also tried to simply bypass most of the script by adding:
delete (every file of this_folder whose name starts with ".")
at the top of “process_folder”. This generated similar errors that the delete statement above gave. Working around this with do shell script does not work since the script halts if one of the folders is without .
files.

The only consistency I can find is that it is the file / folder references that can not be used the way I think they can be used. Can someone help me untangle this mess a little bit?

if you’re trying to delete “.DS_Store” files, note that “._” is not in contents of “.DS_Store”. A hypothetical “.DS_Store", WOULD contain ".”.
If you’re trying to delete every file whose name starts with “.” (invisible?), this may work:

-- This droplet processes both files or folders of files dropped onto the applet 
on open these_items
	repeat with i from 1 to the count of these_items
		set this_item to (item i of these_items)
		set the item_info to info for this_item
		if folder of the item_info is true then
			process_folder(this_item)
		else if (alias of the item_info is false) and ¬
			((the file type of the item_info is in the type_list) or ¬
				the name extension of the item_info is in the extension_list) then
			process_item(this_item)
		end if
	end repeat
end open

-- this sub-routine processes folders 
on process_folder(this_folder)
	set these_items to list folder this_folder with invisibles
	repeat with i from 1 to these_items's length
		set this_item to alias ((this_folder as text) & (item i of these_items))
		set the item_info to info for this_item
		if folder of the item_info then
			process_folder(this_item)
		else
			if (name of item_info) starts with "." then do shell script "rm -f " & quoted form of POSIX path of this_item
		end if
	end repeat
end process_folder

The files I am trying to delete are all the files that hold resource info in "normal files"when they are copied to PC volumes. These files all start with ._ (dot underscore)

myfile.jpg
._myfile.jpg

From what I saw this is what you altered:
if (name of item_info) starts with “.” then do shell script "rm -f " & quoted form of POSIX path of this_item

This does not work since is does not find any files that start with . or ._
Even though they are invisible they are not included in a with invisibles statement.

Then, they must be “unexistent”, not “invisible” :lol:
Try this with a folder you know contains “._whatever” files:

list folder alias "path:to:folder_containing_files_with_dots_in_their_name:"

You should get anything such as:

{"._whatever","normal file.txt"}

Now, this one:

do shell script "rm -f /path/to/folder_containing_files_with_dots_in_their_name/._whatever"

This works for me!
If you include “with invisibles” parameter, you should see ANY file within such folder. You can try also shell’s “ls”. This may return the same results than “list folder whatever with invisibles”:

paragraphs of (do shell script "ls -a /path/to/folder_containing_files_with_dots_in_their_name/")

(this also includes references “.” = myself and “…” = parent directory)

There are several ways to specify the location of a file. The safest one is an alias:

alias "path:to:file"

Some applications will accept a simple path (“path:to:file”), which is a simple string; a “file specification” (perhaps this file doesn’t exist: file “path:to:file”). Also, the Finder can work with its own references (file “whatever” of folder “whatever” of startup disk of application “Finder”). Also, you can send/receive UNIX paths (eg, an applescript-studio application: “/users/whatever/folder/file”).
But most of the times the best reference is an alias, specially when working with the Finder.
NOTE that this way to reference a file -alias- is not a Finder “alias file”.

Anyway, returning to the original question, if you can delete manually these files (eg, from the Terminal), you can do it too via applescript. The code I posted above works for me, and removes successfully any file whose name starts with “.”… Hmmm… Maybe your problem is at a different line of code… Could you post the entire code you are testing?

Here is my code that still does not work (on my machine at least).


-- This droplet processes both files or folders of files dropped onto the applet 
on open these_items
	repeat with i from 1 to the count of these_items
		set this_item to (item i of these_items)
		set the item_info to info for this_item
		if folder of the item_info is true then
			process_folder(this_item)
		else if the name of the item_info starts with "._" then
			process_item(this_item)
		end if
	end repeat
end open

-- this sub-routine processes folders 
on process_folder(this_folder)
	set these_items to list folder this_folder with invisibles
	repeat with i from 1 to the count of these_items
		set this_item to alias ((this_folder as text) & (item i of these_items))
		set the item_info to info for this_item
		if folder of the item_info is true then
			process_folder(this_item)
		else if (name of item_info) starts with "._" then
			do shell script "rm -f " & quoted form of POSIX path of this_item
		end if
	end repeat
end process_folder

This is basically Apples example with a few bits cut off. All the finding files bits are Apples except for the “with invisibles” part.

This should delete any file starting with “." in nesteed folders.
If you substitute “process_item(this_item)” with "do shell script “rm -f " & quoted form of POSIX path of this_item”, this should process, too, files starting with ".
” in the first dropped folder.
This code works for me in folders containing “.DS_Store” files:

on open these_items
	repeat with i from 1 to the count of these_items
		set this_item to (item i of these_items)
		set the item_info to info for this_item
		if folder of the item_info is true then
			process_folder(this_item)
		else if the name of the item_info starts with ".DS" then
			do shell script "rm -f " & quoted form of POSIX path of this_item
		end if
	end repeat
end open

on process_folder(this_folder)
	set these_items to list folder this_folder with invisibles
	repeat with i from 1 to the count of these_items
		set this_item to alias ((this_folder as text) & (item i of these_items))
		set the item_info to info for this_item
		display dialog """ & (name of item_info) & """
		if folder of the item_info is true then
			process_folder(this_item)
		else if (name of item_info) starts with ".DS" then
			do shell script "rm -f " & quoted form of POSIX path of this_item
		end if
	end repeat
end process_folder

Sorry for this silly question… How do you know there are files “._whatever” in your folders before-and-after processing them with this droplet?

I know from listing the folder with the terminal. I have also checked the volume on a PC just to be sure that the terminal is not just caching the listing.

I ran your script and it removed all .DS… files from the folders. Then I replaced “.DS” with “._” and these files do not disapear.

And the dialog you have for the file listing does not list these ._ files. It lists the .DS_Store files but not these ._myfile.jpg files. This is sick?!

Could it be that the underscore character is reserved or treated special in some way? Di I need to somehow escape it? “._” or use something similar to HTML encoding of wierd characters?

Maybe you have an answer to this instead:

I can write a do shell script that uses a wildcard to remove all ._ files in a folder. But if no files match the shell returns an error and the Applescript stops. Can you ignore the "No Match " return from the shell?

do shell script "rm -f " & (the quoted form of the POSIX path of this_item) & “._*”

But then this would not work at all in OS 9, but still better than nothing.

Finally I understand…

You can ignore error using a try-end try statement:

try
     do shell script "rm -f  " & (the quoted form of the POSIX path of this_item) & "._*" 
on error
     --> do anything here if you wish
end try

About the OS 9 stuff, I think that may not exist such problem with “._*” files. You can not use the shell, but the Finder should be able to do it (under OS X it could do it, too, teorically):

set the_item to alias "path:to:._file"
tell app "Finder" to delete the_item

Hey!

Thanks a bunch.

Using the try statement makes it work in X. Wonderful!