Copy or move files using AppleScript

When copying or moving files using the shell, although the tags (red, orange, etc.) are reliably preserved, the comments are often lost. This is why, if you need to copy or move files using scripts, it is much better to do it by envoking AppleScript for this.

Here is a test directory tree:

~/
|- aaa/
   |- bbb/
   |  |- ccc/
   |  |- foo.ext
   |
   |- ddd/
      |- eee/

And below are two ways to copy foo.ext by envoking AppleScript: using the -e option and using the heredoc notation.

I ask here to help me (and other people who will find it useful), to improve either of the two versions so that it can be used like

cp-or-mv-with-applescript.sh <source> <target>

The first version

  • It is essentially 3 scripts within 1
  • Comments must be removed
osascript -l AppleScript \
-e 'set currentFolder to do shell script "pwd"' \
-e 'set currentFolder to ((POSIX file currentFolder) as text)' \
-e 'tell application "Finder"' \
\
  # to the same folder (foo.ext -> foo copy.ext) \
  -e 'duplicate file (currentFolder & "foo.ext")' \
\
  # to ~/aaa/bbb/ccc/ \
  -e 'duplicate file (currentFolder & "foo.ext") to folder (currentFolder & "ccc:")' \
\
  # to ~/aaa/ddd/ \
  -e 'set parentFolder to ((container of folder currentFolder) as text)' \
  -e 'duplicate file (currentFolder & "foo.ext") to folder (parentFolder & "ddd:")' \
\
  # to ~/aaa/ \
  -e 'set parentFolder to ((container of folder currentFolder) as text)' \
  -e 'duplicate file (currentFolder & "foo.ext") to folder parentFolder' \
\
-e 'end tell'

The second version

# to ~/aaa/bbb/ccc/
osascript << SCRIPT
set currentFolder to "$(pwd)" as POSIX file as text
tell application "Finder"
  duplicate file (currentFolder & "foo.ext") to folder (currentFolder & "ccc:")
end tell
SCRIPT
# to ~/aaa/ddd/
osascript << SCRIPT
set currentFolder to "$(pwd)" as POSIX file as text
set parentFolder to "$(dirname $PWD)" as POSIX file as text
tell application "Finder"
  duplicate file (currentFolder & "foo.ext") to folder (parentFolder & "ddd:")
end tell
SCRIPT
# or
osascript << SCRIPT
set currentFolder to "$(pwd)" as POSIX file as text
tell application "Finder"
  set parentFolder to (container of folder currentFolder) as text
  duplicate file (currentFolder & "foo.ext") to folder (parentFolder & "ddd:")
end tell
SCRIPT

I think (having taken a quick poke around) it is more a case of even when the extended attributes are copied in the shell, Get Info in Finder is getting the comment in the directory’s .DS_Store file. When Finder sets the comment it sets both places and when set at the command line, the .DS_Store doesn’t get the memo there’s been the update.

If you install osxutile, you could use getfcomment and setfcomment to transfer the comment. You could then probably wrap it into a function.

Here’s an example that seems to work for me.

cpwc() {
    if [ "$#" -ne 2 ]; then
        echo "Usage: cpwc <source> <destination>"
        return 1
    fi
    
    # Copy the file
    cp "$1" "$2"
    
    # Exit on error
    if [ $? -ne 0 ]; then
        echo "Failed to copy file."
        return 1
    fi
    
    # Get the Finder comment from the source file
    local comment=$(getfcomment "$1")
    
    # Exit on error (which could be just fine)
    if [ $? -ne 0 ]; then
        #echo "No Finder comment on source file."
        return 1
    fi
    
    # Set the Finder comment (silently) on the destination file
    setfcomment -s -c "$comment" "$2"
    
    # Exit on error
    if [ $? -ne 0 ]; then
        return 1
    fi
    
    echo "File copied."
}

not exactly what you were asking for, but maybe it will be a useful alternative if you’re willing to use macosxutils.