3

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.

5
  • What is the suffix (.???) of this files?
    – user415185
    Sep 29, 2021 at 16:23
  • 1
    If you changed these icons using Finder’s Get Info window, the images will be in the resource fork (extended attribute) of an invisible file in the folder root. It would probably be easier to just copy the original images.
    – red_menace
    Sep 29, 2021 at 19:34
  • 1
    @red_menace Out of curiosity, shouldn't that affect the kMDItemFSHasCustomIcon value for the folder? I get (null). Or are these unrelated? Also get same with a file when pasting an image into the Get Info icon well.
    – Mockman
    Sep 29, 2021 at 20:32
  • 1
    @Mockman - I’ve never seen the kMDItemFSHasCustomIcon show anything but (null), so I don’t know if it is deprecated, referring to something else, or is just broken. The com.apple.ResourceFork metadata is where the image data is actually stored, but it is a bit of a pain to get at, especially for folders.
    – red_menace
    Sep 29, 2021 at 20:58
  • 1
    @red_menace Thanks for the insight. I find it difficult to track down details for much of the myriad metadata in the filesystem as well as info on icons but this gives me something to look into.
    – Mockman
    Sep 29, 2021 at 23:22

1 Answer 1

1

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.

2
  • 1
    This is brilliant! I will test it asap.
    – Fabio
    Sep 30, 2021 at 10:36
  • 1
    It works like a charm! thank you!!
    – Fabio
    Sep 30, 2021 at 10:52

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .