How to recursively extract custom icons from subfolders and save them in image files

I am migrating from MacOS to Linux. I have customized the icon of many of my sub-folders in my "Documents" folder. I learned how to do the same in Linux, using image files, and now I would like to transport all my custom icons to my new system.

Since the number is quite high, I would like to automate this process: recursively copy the custom icon of all the subfolders, and save each of them in a separate image file (.png format?).

Maybe this could be done with an Automator script, but I am not proficient with that.


The example shell script code, shown below, what tested under macOS Catalina saved as a shell script and executed in Terminal.

It makes use of the the third-party utility fileicon, which is a shell script that use all native macOS functionality to extract the icons from the folders that have a custom icon. I used the manual installation instructions on the linked web page.

The example shell script code creates a working folder within the Documents folder with the naming convention of, e.g., Documents Folders Images - 1632963703 where e.g. 1632963703 is the seconds since epoch. Within this folder, a hierarchical folder structure is created in the qualified pathname for each folder from the Documents folder, that has a custom icon, where an .icns file is created as the extracted image and a .png file created from it. The files/folders are named according the name of the folder with the custom icon. This way you have no problem knowing where they go once moved to Linux.

To use the example shell script code, in Terminal, run the following compound command:

f='extracticons'; touch "$f"; open -e "$f"; chmod +x "$f"

Copy and paste the example shell script code, shown below, into the opened extracticons document, then save it.

You should then move the extracticons shell script to a directory located within the shell's PATH.

I moved it to /usr/local/bin, e.g,:

sudo mv -v extracticons /usr/local/bin/

Now it's ready for use, just type extracticons and press enter.


Example shell script code:

#!/bin/zsh

doc_dir="$HOME/Documents"
icns_dir="${doc_dir}/Documents Folders Images - $(date +%s)"

while IFS= read -r line; do
    [[ "${line}" =~ ($HOME/)(Documents/.*)(/Icon) ]] || continue
    mkdir -p "${icns_dir}/${match[2]}"
    cd "${icns_dir}/${match[2]}" || exit
    printf '%s\n' 'Creating .icns file...'
    fileicon get "${match[1]}${match[2]}"
done < <(find "${doc_dir}" -type f -name 'Icon?' -print)

while IFS= read -r line; do
    dir_path="${line%/*}"
    file_name="${line##*/}"
    cd "${dir_path}" || exit
    printf '%s\n' 'Creating .png file...'
    sips -s format png "${file_name}" --out "${file_name%.*}.png"
done < <(find "${icns_dir}" -type f -name '*.icns' -print)

cd "${icns_dir}" || exit
printf '%s\n' 'Creating Zip Archive...'
zip -r 'DocumentsFoldersIcons.zip' 'Documents'
printf '%s\n' "Deleting ${icns_dir}/Documents"
rm -r "${icns_dir}/Documents"

Notes:

The last block of code in the example shell script code creates a zip archive file of the hierarchical folder structure and then cleans up by deleting the hierarchical folder structure, leaving a file named DocumentsFoldersIcons.zip containing all of the icons created with their paths recursed. You can always comment it out or remove the rm command if you want.

This answer only covers the extraction of custom icons and the creation of a .png file from the .icns file. Assigning the icons to folders under Linux is outside the scope of appropriate questions for Ask Different. Posting a question at Ask Ubuntu or Super User would be more appropriate for the Linux side of things.

On a side note though, once you have extracted the DocumentsFoldersIcons.zip files on the Linux system, if you need different sizes of the image other than the one extracted by sips, you can use icns2png to extract all the icons in the .icns files to the various sizes within by doing the following in a Terminal:

cd '/path/to/extracted/Documents'
find . -type f -name '*.icns' -execdir sh -c 'icns2png -x "$1"' sh {} \;

Note that this assumes icns2png has been installed.

Then in each folder you will find, e.g.,:

Foldername.icns
Foldername.png
Foldername_16x16x32.png
Foldername_32x32x32.png
Foldername_48x48x32.png
Foldername_128x128x32.png
Foldername_256x256x32.png
Foldername_512x512x32.png

The example shell script code was tested in Terminal under macOS Catalina with Language & Region settings in System Preferences set to English (US) — Primary and worked for me without issue1.

  • 1 Assumes necessary and appropriate settings in System Preferences > Security & Privacy > Privacy have been set/addressed as needed.



The example shell script code is just that, an example, and sans any included error handling does not contain any additional error handling as may be appropriate, needed, or wanted. The onus in upon the user to ensure the script if fit for use for ones purpose.