Polle
Polle

Reputation: 67

Embedding a shell command in applescript not working - how do I support names with spaces?

I can't get this to work. I need to rename all of the .CR2 files to *.cr2 in the chosen directory. I need this to work on files with a space in the filename too.

set varChosenfolder to POSIX path of (choose folder)
(do shell script "for file in " & varChosenfolder & "*.CR2; do mv '$file' '`basename '$file' .CR2`.cr2'; done")

I want to do this with a shell script and not be the tell command to "Finder", as I find shell scripts to work much faster.

EDIT: I somehow managed to put something together, although I'm not sure this is the optimal method. I started out using 'ls', however I had difficulties making that work with foldernames and filenames with spaces in the names. So I ended up with this:

on fixextensions()
try

set varFilestorename to (do shell script "find " & varChosenfolder & " -type f -depth 1 | grep '.CR2'")


    set AppleScript's text item delimiters to {return}
    set varOldfilenames to paragraphs of varFilestorename as text
    set AppleScript's text item delimiters to ""


    repeat with i in paragraphs of varOldfilenames
        set varSinglenewfilename to ((text 1 thru -4 of i) & "cr2")
        (do shell script "mv " & "\"" & i & "\"" & space & "\"" & varSinglenewfilename & "\"")
    end repeat
on error
    #       display dialog "No CR2 files with capital letters"
end try
end fixextensions

Upvotes: 0

Views: 92

Answers (1)

Charles Duffy
Charles Duffy

Reputation: 295288

Best practice is never to generate code by substituting dynamically-generated contents such as filenames. If it's necessary to do so, then one can avoid serious security bugs by using constructs that quote the content in question to ensure that it can't be malicious if parsed as code (and/or contain contents that cause it to escape its quoting and be parsed as code).

set varChosenfolder to POSIX path of (choose folder)
do shell script "for file in " & quoted form of varChosenfolder & "/*.CR2; do mv \"$file\" \"$(basename \"$file\" .CR2)\".cr2; done"

The actual command this runs differs only in whitespace (and the specifics of the path used at invocation) from the following:

sh -c '
  for file in /path/to\ your/folder/*.CR2; do
    mv "$file" "$(basename "$file" .CR2)".cr2;
  done
'

Notably, this script:

  • Only substitutes a value which AppleScript was told to ensure was safe with the quoted form of construct, but is otherwise entirely hardcoded.
  • Has all expansions performed inside double quotes, including the expansion of the basename command's result; this prevents literals with whitespace or glob character from behaving undesirably.

Upvotes: 1

Related Questions