How can I use Automator Service to create a .zip file from two original files using the same name?
Yes, this is doable, and in more then one way too.
The following describes a minimal no frills workflow:
In Automator, select: File > New > Service
Set: Service receives selected files or folders in Finder
Add the following Actions:
-
Run Shell Script
- Settings: Shell: /bin/bash and Pass input: as arguments
- Replace all of the default code with just:
echo "$(basename "${1%.*}")"
- This returns the filename portion of the first file, sans its extension, and is what Set Value of Variable gets set to.
-
Set Value of Variable
- Click, Variable: New variable... and give it an appropriate name, e.g.: ZipFileName
-
Get Selected Finder Items
- Set Options to: [√] Ignore this action's input
- Note that this creates a wanted break between this action and the previous action.
- Set Options to: [√] Ignore this action's input
-
Create Archive
- Set Save as: to ZipFileName by drag and drop of the variable from the Variable section at the bottom of the workflow pane.
- Set Where: to Same Folder as Input.
Update to add moving files to the Trash:
Add these additional Actions:
-
Get Selected Finder Items
- Set Options to: [√] Ignore this action's input
- Note that this creates a wanted break between this action and the previous action.
- Set Options to: [√] Ignore this action's input
Move Finder Items to Trash
Save the Automator Service Workflow giving it an appropriate name, e.g.: Compress File Set
Now in Finder, select two of the matching filenames, sans having different extensions, then right-click and select Compress File Set, from the services section of the context menu.
Note: This minimal no frills Automator Service Workflow employs no error checking. It relies on one to properly select the two matching filenames, sans the differing extensions, to be compressed together in a zip archive of the first file's filename, sans its extension.
See the second workflow, below the picture, that employs conditional error checking and handling and has some features the no frills workflow doesn't have.
Second Automator Service Workflow
The following workflow has conditional error checking and handling. It can be used instead of the no frills workflow above:
It uses as single Run Shell Script action to handle the entire process.
In Automator, select: File > New > Service
Set: Service receives selected files or folders in Finder
-
Add a Run Shell Script Action
- Settings: Shell: /bin/bash and Pass input: as arguments
- Replace all of the default code with the code show further below.
Save the Automator Service Workflow giving it an appropriate name, e.g.: Compress File Set
Now in Finder, select two of the matching filenames, sans having different extensions, then right-click and select Compress File Set, from the services section of the context menu.
This Automator Service Workflow employs the following conditional error checking and handling:
- Makes sure only two items are selected in Finder.
- Makes sure both files have the same filename, sans extension.
- Makes sure the filename extensions match the expected type, 'cdg' and 'mp3'.
- Employs appropriate error handling if processing errors out.
- Is coded to be able to give both verbal and visual messages as appropriate.
- Is set to use Notification Center for visual messages, but can be easily changed to speak the messages too.
Frills:
- Makes the same sounds when compressing and or moving the files to the Trash in Finder.
- Can be set to play this event sound or not, default is to play it.
- Can directly delete the files instead of placing them in the Trash.
- The default is to move the files to the Trash, make this setting change only of you totally understand the finality of this action.
The script has two Functions and a Main section.
-
function CompressSelectedFiles ()
- This handles the grunt work and has the settings for the compress event sound and moving files to the Trash.
-
function NotifyUserMessage()
- This handles notifying the user with the various messages and the settings for the type of notifications, verbal and or visual.
-
Main
- This handles the main logic flow validating conditions are met before processing.
This section does not have user setting as that within the two functions have.
- This handles the main logic flow validating conditions are met before processing.
Read comments throughout the script so as to modify it features appropriately.
Code for Run Shell Script Action:
#!/bin/bash
### Functions ###
function CompressSelectedFiles () {
# Change to the target directory,
# or notify user of failure and exit.
if ! cd "$(dirname "$1")"; then
NotifyUserMessage 'nochgdir'
exit
fi
# Set the two filenames to variables.
f1="$(basename "$1")"
f2="$(basename "$2")"
# Check to see if the target zip archive
# already exists, and if not, create it.
if [[ ! -e "${f1%.*}.zip" ]]; then
# Syntax: zip [options] zipfile file ...
if ! zip "${f1%.*}.zip" "${f1}" "${f2}"; then
NotifyUserMessage 'ziperror'
exit
fi
# # The following lines of code mimic Finder's Compress command
# # as to numerically incrementing an archive's filename. It has
# # been commented out as the user requested to delete the files
# # after I wrote this. I've left it, in case it's found useful.
#
# else
# # The zip archive already exists!
# # Numerically increment the zip filename.
# n=2
# for f in ${f1%.*} *.zip; do
# if [[ "${f1%.*} $n.zip" == "$f" ]]; then
# n="$(( n + 1 ))"
# fi
# done
# # Syntax: zip [options] zipfile file ...
# if ! zip "${f1%.*} $n.zip" "${f1}" "${f2}"; then
# NotifyUserMessage 'ziperror'
# exit
# fi
# Make the same event sound Finder does when compressing files.
# Note: Despite its name, this *is* the sound made by Finder when compressing files.
# If you do not want to hear it, set 'playthis=1' to 'playthis=0'.
playthis=1
[[ $playthis -eq 1 ]] && afplay "/System/Library/Components/CoreAudio.component/Contents/SharedSupport/SystemSounds/system/Volume Mount.aif"
[[ $playthis -eq 1 ]] && sleep 1 # Pause to allow time between event sounds.
fi
# The following was added per user request.
#
# Move File Set to the Trash. So you can then use
# Put Back from the Trash in Finder, if necessary.
# Default is to use the Trash, setting 'trash=1'.
#
# If you don't want to put the files in the Trash,
# just delete them directly, then set 'delete=1'
# and set 'trash=0' when setting 'delete=1'.
#
# WARNING: Setting 'delete=1', this method
# is immediate and irreversible.
trash=1
delete=0
[[ $trash -eq 1 ]] && osascript -e "set theFiles to {}" \
-e "set the end of theFiles to POSIX file \"$1\"" \
-e "set the end of theFiles to POSIX file \"$2\"" \
-e "tell application \"Finder\" to move theFiles to trash"
[[ $delete -eq 1 ]] && rm "$1" "$2"
# Notify user processing is finished.
NotifyUserMessage 'finished'
}
function NotifyUserMessage() {
# Set servicename='' to the name of this service.
servicename='Compress File Set'
# As currently set, messages are sent to the Notification Center.
# If you want a verbal message, change the value of 'verbal=0'
# to 'verbal=1'. If your OS version is older and doesn't support
# Notification Center from scripts, e.g. OS X 10.8, then change
# 'visual=1' to 'visual=0'. Whichever your preference is, set 0
# for false and 1 for true.
verbal=0
visual=1
case $1 in
selected )
msg='This service requires two files to be selected.'
[[ $verbal -eq 1 ]] && say "$msg"
[[ $visual -eq 1 ]] && osascript -e "display notification \"$msg\" with title \"$servicename Error\""
;;
filenames )
msg='The filenames, sans extensions, are mismatched.'
[[ $verbal -eq 1 ]] && say "$msg"
[[ $visual -eq 1 ]] && osascript -e "display notification \"$msg\" with title \"$servicename Error\""
;;
extensions )
msg='One or both file extensions are not the expected type.'
[[ $verbal -eq 1 ]] && say "$msg"
[[ $visual -eq 1 ]] && osascript -e "display notification \"$msg\" with title \"$servicename Error\""
;;
nochgdir )
msg='An error occurred while trying to change directory.'
[[ $verbal -eq 1 ]] && say "$msg"
[[ $visual -eq 1 ]] && osascript -e "display notification \"$msg\" with title \"$servicename Error\""
;;
ziperror )
msg='An error occurred while compressing the files.'
[[ $verbal -eq 1 ]] && say "$msg"
[[ $visual -eq 1 ]] && osascript -e "display notification \"$msg\" with title \"$servicename Error\""
;;
finished )
msg='The selected files have been compressed.'
[[ $verbal -eq 1 ]] && sleep 1 # Pause so as not to step on previous event sound.
[[ $verbal -eq 1 ]] && say "$msg"
[[ $visual -eq 1 ]] && osascript -e "display notification \"$msg\" with title \"$servicename\""
;;
esac
}
### Main ###
# Validate Conditions #
# Make sure only two items are selected in Finder.
if [[ $# -eq 2 ]]; then
# Make sure both files have the same filename, sans extension.
if [[ ${1%.*} == "${2%.*}" ]]; then
# Make sure the filename extensions match the expected type, 'cdg' and 'mp3'.
if [[ ${1##*.} =~ [cC][dD][gG] ]] && [[ ${2##*.} =~ [mM][pP]3 ]]; then
# All conditions met, create zip archive.
CompressSelectedFiles "$1" "$2"
elif [[ ${2##*.} =~ [cC][dD][gG] ]] && [[ ${1##*.} =~ [mM][pP]3 ]]; then
# All conditions met, create zip archive.
CompressSelectedFiles "$1" "$2"
else
NotifyUserMessage 'extensions'
fi
else
NotifyUserMessage 'filenames'
fi
else
NotifyUserMessage 'selected'
fi