Shell Script syntax

Hi there

I have the following piece of script:

set thefolderfrom to POSIX path of (path to movies folder) & "Complete"
set listfoldersfrom to paragraphs of (do shell script "find " & quoted form of thefolderfrom & " -type d  -depth 1 | grep -v .DS_Store | grep -v .localized | grep -v .BackupIcon.icns |grep -v Icon |sed 's:" & "/::'")
display dialog listfoldersfrom as text
set cntfolders to count (listfoldersfrom)
set filestoplay to ""
if cntfolders > 0 then
	repeat with foldercheck in listfoldersfrom
		set filestoplay to filestoplay & paragraphs of (do shell script "find " & quoted form of foldercheck & " -iname '*.mov' -type f  -depth 1 | grep -v .DS_Store | grep -v .localized | grep -v .BackupIcon.icns |grep -v Icon |sed 's:" & "/::'")
	end repeat
	display dialog filestoplay as text
end if

The idea is to get a list of all the files in the subfolder of the Movies folders that have the extension “.mov”. I know there is a quicker way than the above but bear with me as this is a small part of a large script that is structured in a particular way and expects the result in a particular way.

Anyway, the problem is that the result returned for listfoldersfrom is fine - I get a list of paths “Users/macmini/etc”, whereas the result for filestoplay always returns results beginning “Usersmacmini/etc”

ie the result of the search for filestoplay always misses the first backslash in the file path for every file it finds. As far as I can tell, the two find shell scripts are identical (apart from the fact that the first searches for folders rather than files). So I am at a loss.

Can someone point out the syntactic error here??


It looks like foldercheck doesn’t start with a slash, but you’re still using sed to replace the first slash it finds.

I tried removing the sed part but keep getting an exit on zero error with the script as follows:

do shell script "find " & quoted form of foldercheck & " -iname '*.mov' -type f  -depth 1 | grep -v .DS_Store | grep -v .localized | grep -v .BackupIcon.icns | grep -v Icon")

I’m assuming you mean “The command exited with a non-zero status.” That should mean that grep didn’t find anything.

It should find something though, as when I run the script without the sed part, it returns the correct files EXCEPT that the path begins "Usermacmini/etc’ rather than “User/macmini/etc”

If I use this script:

do shell script "find " & quoted form of foldercheck & " -iname '*.mov' -type f -depth 1 | grep -v .DS_Store | grep -v .localized | grep -v .BackupIcon.icns | grep -v Icon |sed 's:" & ";::'")

… the result is properly returned with “User/macmini/etc”. But it is a hack, as if the file name/path contains a “;”, presumably the “;” will be removed. So, I am just not understanding why removing the sed part gives me an applescript error, rather than simply returning the full path…


… better hack is having the sed part as follows:

sed 's:/" & "/::'"

Replaces first backslash with a backslash!!!

Still don’t understand why I simply can’t remove the sed part of the shell script…


Removing sed means the result of the shell script comes from grep, which exits with a non-zero value when a match is not found; do shell script “[s]ignals an error if the shell script exits with a non-zero status.”

If you pipe the results of grep (an empty string) to sed, then sed does its business and returns the resulting string (still an empty string).

I don’t understand why you even need grep in this script; None of the items you’re trying to exclude should be matched by find (and if Icon is anywhere in the path of those files, it will be removed when it shouldn’t).

Edit: If for some reason you do need to exclude names, then just do it directly with find:

choose folder
set foldercheck to text 1 thru -2 of POSIX path of result

do shell script "/usr/bin/find " & quoted form of foldercheck & " -type f -depth 1" & ¬
	" -not -name '.DS_Store' -not -name '.localized' -not -name '.BackupIcon.icns' -not -name 'Icon'"

You are quite right, Bruce

Thanks for the explanation.

Have changed it to:

paragraphs of (do shell script "find " & quoted form of foldercheck & " -iname '*.mov' -type f  -depth 1")

Even though you got things working I thought I would throw in a few additional points on shell scripting topics that came up in the thread. The first three have been addressed in your application by eliminating sed and grep. The last is still a potential (though unlikely) problem.

If you want to ignore the return code of the last program in a do shell script add “;true” to the end. The true program just returns a success exit value (zero). If it is the last program executed by the shell, then the shell’s exit value will also be zero and do shell script will not throw an AppleScript error. This is what Bruce was talking about. For some reason grep was returning non-zero. sed pretty much always returns zero. true will always return zero.

To erase just a leading slash (leaving alone any internal slashes) with sed, use sed -e ‘s:^/::’. The caret (^) anchors the regular expression to the beginning of the string (the beginning of the each line in sed).

Also, there is nothing magical about breaking up the AppleScript string literal in the middle of the sed program text. Maybe it was left over after editing a copy-and-paste from an earlier script where the regular expression included variable data.

set a to ".|sed 's:" & "/::'"
set b to ".|sed 's:/::'"
return a is b --> true

If any of the file paths printed by find (which will include the string value of foldercheck) have linefeeds or carriage returns, then paragraphs of will not reliably split the output into individual file paths (since it would also break things up in the middle of the file paths that contain LF or CR) . It is probably unlikely, but it is something to watch out for. There are workarounds, but they are more complicated (-print0 in find, text item delimiters equal to {ASCII character 0}, inability to use sed (since it only knows how to process lines, not the more general idea of null delimited strings), etc.).

That’s not something I’ve ever concerned myself with.

From the grep man page:

Right. I wrote “for some reason” because kiwilegal seemed to indicate that the script was producing output, even though grep would probably have been retuning zero in that case (assuming there was no error). Looking at the original script, it was probably the case that some of the foldercheck paths had no matching files paths (lines for grep to select), but others did.