Create a zip file using an Automator Service

I am trying to create a service in Automator in Mac OS X Mountain Lion. The command that I want to use is as follows:

zip zip-file.zip "$@"

And here is a screen capture of what I did:

enter image description here

It works. But two problems:

  1. zip-file.zip is placed in my home directory ~\. I want to place the zip file in where the original files are.

  2. zip-file.zip contains the folder structure of the specified files beginning from the root. I want to only include files, or just from the closest parent directory.

What should I do?


Why not just use the Create Archive action rather than shell scripting?

I created a quick one that has four steps.

  1. selects a folder (Ask for Finder Items - Folders only)
  2. selects the files (Get Folder Contents)
  3. filters the items to not selects any subfolders (Filter Finder Items)
  4. pass the files to the Create Archive action

enter image description here


I was able to modify the shell script to obtain the desired results, with help from https://stackoverflow.com/questions/12340846/bash-shell-script-to-find-the-closest-parent-directory-of-several-files/12341334#12341334

enter image description here

declare -a names
declare -a parts
declare i=0

names=("$@")
name="$1"
while x=$(dirname "$name"); [ "$x" != "/" ]
do
    parts[$i]="$x"
    i=$(($i + 1))
    name="$x"
done

for prefix in "${parts[@]}" /
do
for name in "${names[@]}"
    do
        if [ "${name#$prefix/}" = "${name}" ]
            then continue 2
        fi
    done
    dir="$prefix"
    break
done

cd "$dir"

for file in "${names[@]}"
do
    zip zip-file.zip -r "${file#$dir/}" -x *.DS_Store
done

I don't use Automator, but I have a solution that I use to zip files. Put in your desired filename and password in the beginning of the script and export as an application. Drag and drop your files into the droplet icon and voilà a zip archive is created in the same folder as the original files.

on open theItems

    set passwd to "yourPassword"
    set archiveName to "yourArchive"

    tell application "Finder"
            if theItems's length > 1 then
                    set fileName to archiveName & ".zip"
            else
                    set fileName to name of item 1 of theItems & ".zip"
            end if
            --remove existing archive file with same filename
            try
                    set archiveFile to ((container of (item 1 of theItems) as Unicode text) & fileName)
                    if exists file archiveFile then
                            delete file archiveFile
                    end if
            end try
    end tell

    repeat with thisItem in theItems
            set itemPath to quoted form of (POSIX path of thisItem)
            tell application "Finder"
                    set parentFolder to POSIX path of (container of thisItem as alias)
            end tell
            set zipFile to quoted form of (parentFolder & fileName)
            set cmd to "zip -P " & passwd & " -rj " & zipFile & " " & itemPath & " -x *.DS_Store"
            do shell script cmd
    end repeat

end open