简体   繁体   中英

Create an Applescript or Shell Script to Unzip and Rename Files?

I have several folders of .zip files that I would like to do the following to:

  • Extract the enclosed files or folders to the same location as the .zip
  • Rename the resulting file or folder to whatever the name of the .zip file was
  • Delete the .zip file

The .zip file always contains either a single file or a single folder, so no worries about renaming the wrong folder.

I only have a little experience with Applescript and pretty much none with shell scripting. Can anyone help or make any suggestions?

Thanks!

Unzipping a file is not the hard part of your question. The hard part is the renaming because we do not know what files/folders are unzipped. So the strategy here is to get a list of all the items in the folder prior to unzipping, get another list of all the items in the folder after unzipping, then compare the 2 lists. The items that are in the second list that aren't in the first list are the unzipped items... so we can rename them if their name is not the same as the zip file.

Suggestion : to learn applescript, go here and do the tutorials named "AppleScript Tutorial for Beginners". That's how I learned. They're simple to do and you'll learn a lot. Good luck.

-- get the folder containing the zip files
set folderOfZips to (choose folder) as text

tell application "Finder"
    -- get the zip files from the chosen folder
    set zipFiles to files of folder folderOfZips whose name extension is "zip"

    repeat with aZip in zipFiles
        -- we use this when renaming the unzipped files
        set zipName to text 1 thru -5 of (get name of aZip)

        -- get a list of all the items in the folder before unzipping
        set origItems to name of items of folder folderOfZips

        -- unzip the item
        my unzipItem(aZip as text, folderOfZips)

        -- get a list of all the items in the folder after unzipping
        set nowItems to name of items of folder folderOfZips

        -- compare the 2 lists of items, before and after unzipping
        repeat with i from 1 to count of nowItems
            set thisItem to item i of nowItems

            -- if thisItem is not in origItems then it means this is one of the unzipped files, so we rename it
            if thisItem is not in origItems then
                set thisItemPath to folderOfZips & thisItem
                set ext to name extension of item thisItemPath
                if ext is "" then
                    set newname to zipName
                else
                    set newname to zipName & "." & ext
                end if
                if newname is not thisItem then
                    try
                        set name of item thisItemPath to newname
                    end try
                end if
            end if
        end repeat
        move aZip to trash
    end repeat
end tell

tell me
    activate
    display dialog "Finished!" buttons {"OK"} default button 1 with icon note
end tell

on unzipItem(zipPath, destinationFolder)
    do shell script "/usr/bin/ditto -xk " & quoted form of POSIX path of zipPath & space & quoted form of POSIX path of destinationFolder
end unzipItem

Here is another approach:

set mainFolder to (path to desktop as text) & "My Folder"
tell application "Finder" to set myZips to (every file of folder mainFolder whose name extension is "zip") as alias list
repeat with aZip in myZips
    set zipName to itemName(aZip)
    tell application "System Events"
        set newItem to open aZip
        set newItem's name to zipName
        delay 1
        delete aZip
    end tell
end repeat

on itemName(anItem)
    tell application "System Events" to set {name:fileName, name extension:nameExtension} to anItem
    set baseName to text 1 thru ((get offset of "." & nameExtension in fileName) - 1) of fileName
end itemName
temp=$(mktemp -d -t zip)
trap "rm -r $temp" EXIT
cd ~/Desktop

find . -name \*.zip | while IFS= read -r f; do
  if [[ $(zip -sf "$f" | awk 'END{print $2}') -eq 1 ]]; then
    unzip "$f" -x __MACOSX/* -d $temp
    for file in $temp/*; do
      ext=${file##*.}
      mv "$file" "${f%.zip}.$ext"
    done
  elif [[ $(zip -sf "$f" | sed '1d;$d' | awk -F/ '!a[$1]++' | wc -l) -eq 1 ]]; then
    unzip "$f" -x __MACOSX/* -d $temp
    mkdir -p "${f%.zip}"
    mv $temp/*/* "${f%.zip}"
    rm -r $temp/*
  else
    unzip "$f" -x __MACOSX/* -d "${f%.zip}"
  fi
done
  • If an archive only contains one file, the file is renamed to have the same basename as the archive
  • If all members are in one top level folder, the folder is renamed to have the same basename as the archive
  • Otherwise a new containing folder is created

If the archives have AppleDouble files, unzip creates a __MACOSX folder instead of converting them back to extended attributes or other metadata. unar would preserve the information in AppleDouble files.

These would always create a folder with the same name as the archive:

for f in ~/Desktop/**/*.zip; do unzip "$f" -d "${f%.zip}"; done
find ~/Desktop -name \*.zip | parallel unzip {} -d {.}

If archive.zip was normally extracted to archive/ , the commands above would extract it to archive/archive/ .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM