Weird behaviour with find shell script

I have a folder (thefolderfrom) in which subfolders exist, which may contain .avi files. I want to move the .avi files from the subfolders and delete the subfolders.

As part of the script, I have this:

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:" & "/::'")
repeat with foldercheck in listfoldersfrom
	set filestotransfer to paragraphs of (do shell script "find " & quoted form of foldercheck & " -iname '*.avi' -type f  -maxdepth 1 | grep -v .DS_Store | grep -v .localized | grep -v .BackupIcon.icns |grep -v Icon |sed 's:" & foldercheck & "/::'")
	-- (rest of script omitted)
end repeat

The first instruction gets a list of subfolders in thefolderfrom. The repeat loop then checks each subfolder to see if there are any .avi file(s) in it. The result on each part of the loop is a list of files in filestotransfer. However, when the the name of the subfolder contains a square bracket, for example, the result in filestotransfer is is not just the .avi file name(s) inside the subfolder, but instead is the whole path to the file. When this happens, it throws out the rest of the script.

What is going on here? It has something to do with the last “& foldercheck” in the set filetotransfer line of code, I think. I tried adding “quoted form of” just before the last “& foldercheck”, but this did not help.

BTW, having a single open [ in the subfolder name, without a corresponding ], sends the script into error:

Any suggestions?

Thanks

Hi kiwilegal,

Maybe it would be easier to find the AVI files with code like follows


-- using the desktop folder as an example
tell application "Finder"
	set avifiles to every file of (entire contents in desktop) whose name ends with ".avi"
end tell

Or:


set avipaths to paragraphs of (do shell script "mdfind -onlyin /Users/martin/Desktop/ \"kMDItemFSName == '*.avi'\"")

Just ideas :slight_smile:

Hi Martin

Thanks for your reply.

I want to avoid using Finder.

Have tried the mdfind solution. However, that returns full paths rather than just the file name. But at least it does not crash out when there is a single [ in the file name. No doubt this is because SED dos not feature in your script. However, I really need the result to be the file names alone, without the path…

Cheers

But if you want to move the files, you need also the paths

Good point! I should have included my whole script. I am using mv to rename the files as they are moved. So I need to isolate the name of the file so I can rename it correctly. I have the folder path in another variable…

… am also building a list of transferred files… Would need to restructure parts of the script (and build in parsing) if I cannot isolate the name of the file in the shell script…

Will do that if no other solution.

Cheers

you can strip the filename with text item delimiters

e.g.


set avipaths to paragraphs of (do shell script "mdfind -onlyin " & quoted form of thefolderfrom & " \"kMDItemFSName == '*.avi'\"")
set {TID, text item delimiters} to {text item delimiters, "/"}
repeat with onePath in avipaths
	set fileName to last text item of onePath
	-- do something
end repeat
set text item delimiters to TID

Note: consider, that text item delimiters are set to “/” during the whole repeat loop in this example

Cheers,Stefan.

If I am to adopt text delimiters approach, I’d better harmonize shell script finds as well to avoid surprise. Is there a way of using mdfind to search in a particular folder for subfolders? I am looking to update the first line of my code.

Thanks

Try something like this:

choose folder with prompt "Choose source folder:" without invisibles
set sourceFolder to POSIX path of result

choose folder with prompt "Moves files to this folder:" without invisibles
set destinationFolder to POSIX path of result

-- Move files
do shell script "/usr/bin/find " & quoted form of sourceFolder & ¬
	" -type f -mindepth 2 -maxdepth 2 -iname '*.avi' -print0" & ¬
	" | /usr/bin/xargs -0 -J % /bin/mv -n -v % " & quoted form of destinationFolder

-- Delete empty folders
do shell script "/usr/bin/find " & quoted form of sourceFolder & ¬
	" -type d -maxdepth 1 -empty -delete"

Also:

choose folder with prompt "Choose source folder:" without invisibles
set sourceFolder to POSIX path of result

do shell script "/usr/bin/find " & quoted form of sourceFolder & ¬
	" -type f -mindepth 2 -maxdepth 2 -iname '*.avi' -print0" & ¬
	" | /usr/bin/xargs -0 /usr/bin/basename"

Ahh! I know why I am using find instead of mdfind. I cannot control folder depth of finds with mdfind (which I need to do). Back to drawing board…

Bruce

While I confess to not understanding the syntax at all, your scripts seem to do the trick, bar the renaming as the file is moved. I had a shell script to get the date:

set datestamp to (do shell script "date +%Y-%m-%d") & " "

. Which I then added to the front of the file name as it moved across.

In the mix of hieroglyphics you have provided, can this step be incorporated in the shell scripted move?

Many thanks

Thanks for everyone’s help.

Went with Stefan’s text delimiters approach in the end because I understood it and it was the easiest to integrate into my current script.

Cheers

Try something like this:

choose folder with prompt "Choose source folder:" without invisibles
set sourceFolder to quoted form of (text 1 thru -2 of POSIX path of result)

choose folder with prompt "Moves files to this folder:" without invisibles
set destinationFolder to quoted form of POSIX path of result

-- Move files
do shell script "/usr/bin/find " & sourceFolder & ¬
	" -type f -mindepth 2 -maxdepth 2 -iname '*.avi'" & ¬
	" | /usr/bin/ruby -e 'require \"date\"; today = Date.today.to_s;" & ¬
	" STDIN.readlines.each {|path| File.rename(path.chomp, ARGV[0] + today + File.basename(path.chomp)) }' " & ¬
	destinationFolder

-- Delete empty folders
do shell script "/usr/bin/find " & sourceFolder & ¬
	" -type d -maxdepth 1 -empty -delete"

Bruce

Thanks for this.

Something funny going on though. Source folder still there after running script. Destination folder populated with a whole bunch of stuff from somewhere (with date added to beginning of each file - thanks). And, presumably, the delete folder command deleted the folder from whence it all came. But because the delete command does not move things to trash, I do not know what/where source folder has gone.

I note that the script for getting the source folder has changed. Is there an error in there?

I am left wondering what folder has been deleted, if not the one I selected…

Cheers

Empty subfolders of the folder you selected are deleted. That could be changed to delete the selected folder itself.

Cheers, Bruce

I guess I must have selected a wrong folder. Any way to have the last part of the script send to trash rather than delete outright?

Thanks

Try something like this:

choose folder with prompt "Choose source folder:" default location (POSIX file "/") without invisibles
set sourceFolder to POSIX path of result

choose folder with prompt "Moves files to this folder:" without invisibles
set destinationFolder to POSIX path of result

-- Move files
do shell script "/usr/bin/find " & quoted form of (text 1 thru -2 of sourceFolder) & ¬
	" -type f -mindepth 2 -maxdepth 2 -iname '*.avi'" & ¬
	" | /usr/bin/ruby -e 'require \"date\"; today = Date.today.to_s;" & ¬
	" STDIN.readlines.each {|path| File.rename(path.chomp, ARGV[0] + today + File.basename(path.chomp)) }' " & ¬
	quoted form of destinationFolder

-- Delete source folder
(POSIX file sourceFolder) as alias
tell application "Finder" to delete result