0

Sources

Details

My script is based on @btd1337's Uratu Icons script for leaving only the third-party icons, but this script is not compatible with my icons theme project, because:

  • Yaru++ and Canonical's Yaru have different hierarchies/trees;
  • Yaru++ uses the format SVG and Yaru uses the format PNG.

So I rewrote a script in Shell Script to locate the directories and subdirectories of original Yaru, generate the output of all icons of each subdirectory to text files, and enter into the Yaru++ folder, list the text files to remove the files that already exist and leave only the third-party icons. I also proivided a compressed file for easing your analysis at the end of detail.

Pay attention to the sample and small trees of Yaru++ and Yaru:

  • Tree of Yaru++:

    Yaru++
    ├── actions
    │   ├── 16
    │   │   ├── button_cancel.svg
    │   │   └── window-close.svg
    │   ├── 48
    │   │   ├── button_cancel.svg
    │   │   └── window-close.svg
    │   ├── scalable
    │   │   ├── button_cancel.svg
    │   │   └── window-close.svg
    │   └── symbolic
    │       ├── button_cancel-symbolic.svg
    │       └── window-close-symbolic.svg
    └── apps
        ├── 16
        │   ├── office.svg
        │   └── x-office-address-book.svg
        ├── scalable
        │   ├── office.svg
        │   └── x-office-address-book.svg
        └── symbolic
            ├── office-symbolic.svg
            └── x-office-address-book-symbolic.svg
    
  • Tree of original Yaru:

    Yaru
    ├── 16x16
    │   ├── actions
    │   │   ├── button_cancel.png
    │   │   └── window-close.png
    │   └── apps
    │       ├── office.png
    │       └── x-office-address-book.png
    ├── 48x48
    │   ├── actions
    │   │   ├── button_cancel.png
    │   │   └── window-close.png
    │   └── apps
    │       ├── office.png
    │       └── x-office-address-book.png
    └── scalable
        ├── actions
        │   ├── button_cancel-symbolic.svg
        │   └── window-close.svg
        └── apps
            ├── officer-symbolic.svg
            └── x-office-address-book-symbolic.svg
    

Also pay attention to small details:

  • In original Yaru, sizes are folders and directories are subfolders;
  • In Yaru++, directories are folders and sizes are subfolders;
  • Original Yaru's scalable/[directories] is same as Yaru++'s [directories]/symbolic because their icons have the suffix -symbolic.

Now I'll show each part of script in Shell Script:

Observe that directories is the same in both Yaru and Yaru++. The sizes are different.

yaru_original="/usr/share/icons/Yaru"
declare -a yaru_original_sizes=(16x16 24x24 32x32 48x48 scalable)

yaru_plus="$HOME/GitHub/yaru-plus/Yaru++"
declare -a yaru_plus_sizes=(16 24 32 48 symbolic)

declare -a directories=(actions apps categories devices emblems mimetypes places status)

home="$(pwd)" # folder /script

The next part will locate the original Yaru, its folders (size) and subfolders (directory), and it will store to fileList:

echo "PHASE 1 – Locate the directories of original Yaru"

function main() 
{
  cd $yaru_original
  for size in "${yaru_original_sizes[@]}"
  do
      for directory in "${directories[@]}"
      do
          fileList $size $directory
      done
  done
  cd $home
}

Then it will return to the original pwd where the folder script is.

It should output like:

# $yaru_original/$size/directory
/usr/share/icons/Yaru/16x16/actions
/usr/share/icons/Yaru/16x16/apps
/usr/share/icons/Yaru/24x24/actions
/usr/share/icons/Yaru/24x24/apps
/usr/share/icons/Yaru/32x32/actions
/usr/share/icons/Yaru/32x32/apps
/usr/share/icons/Yaru/48x48/actions
/usr/share/icons/Yaru/48x48/apps
/usr/share/icons/Yaru/scalable/actions
/usr/share/icons/Yaru/scalable/apps
# ...

Then the function fileList that stored the subdirectories from the function main, and will generate the output of all icons without extension (because Yaru uses the format PNG and Yaru++ uses the format SVG) of each subdirectory:

echo "PHASE 2 – Generate output files without extension"

function fileList() 
{
    local directory=$1
    local size=$2
    local search_file=($(find $yaru_original/$size/$directory/))
    if [ $search_file ]
    then
        for entry in "${search_file[@]}"
        do
          for i in *; do echo "${i%.png}"; done > $home/$directory-$size.txt
        done
    fi
}

It should output like:

# $home/$directory-$size.txt
/home/gus/script/actions-16x16.txt
/home/gus/script/apps-16x16.txt
/home/gus/script/actions-24x24.txt
/home/gus/script/apps-24x24.txt
/home/gus/script/actions-32x32.txt
/home/gus/script/apps-32x32.txt
/home/gus/script/actions-48x48.txt
/home/gus/script/apps-48x48.txt
/home/gus/script/actions-scalable.txt
/home/gus/script/apps-scalable.txt

Observe that I do not know to subtract x{size} and to replace scalable for symbolic which is not present in original Yaru's array yaru_original_sizes.

Inside a file actions-16x16.txt:

button_cancel
window-close

Now, in the final party, it will read the text files using awk and printing the extension .svg, and will remove the files that already exist in Yaru, from Yaru++:

echo "PHASE 3 – Remove the files that already exist in Canonical's original Yaru"

function removeList()
{
  cd $yaru_plus
  for directory in "${directories[@]}"
  do
      for size in "${yaru_plus_sizes[@]}"
      do
          rm $(awk '{ print $0".svg" }' $home/$size-$directory.txt)
      done
  done
}

main

Output of awk '{ print $0".svg" }' $home/$size-$directory.txt:

# awk '{ print $0".svg" }' /home/gus/script/actions-16x16.txt
button_cancel.svg
window-close.svg

Output of rm $(awk '{ print $0".svg" }' $home/$size-$directory.txt):

rm /home/gus/GitHub/yaru-plus/Yaru++/actions/16/button_cancel.svg
rm /home/gus/GitHub/yaru-plus/Yaru++/actions/16/window-close.svg
rm /home/gus/GitHub/yaru-plus/Yaru++/actions/48/button_cancel.svg
rm /home/gus/GitHub/yaru-plus/Yaru++/actions/48/window-close.svg
rm /home/gus/GitHub/yaru-plus/Yaru++/actions/symbolic/button_cancel-symbolic.svg
rm /home/gus/GitHub/yaru-plus/Yaru++/actions/symbolic/window-close-symbolic.svg
rm /home/gus/GitHub/yaru-plus/Yaru++/apps/16/office.svg
rm /home/gus/GitHub/yaru-plus/Yaru++/apps/16/x-office-address-book.svg
rm /home/gus/GitHub/yaru-plus/Yaru++/apps/48/office.svg
rm /home/gus/GitHub/yaru-plus/Yaru++/apps/48/x-office-address-book.svg
rm /home/gus/GitHub/yaru-plus/Yaru++/apps/symbolic/office-symbolic.svg
rm /home/gus/GitHub/yaru-plus/Yaru++/apps/symbolic/x-office-address-book-symbolic.svg

I will provide a small compressed folder for easing your analysis: https://github.com/Bonandry/yaru-plus/files/5013472/UnixStackExchange.zip

Result

The script was unsuccessful because the error output:

find: ‘/usr/share/icons/Yaru/16x16/128x128/’: No file or folder
find: ‘/usr/share/icons/Yaru/24x24/128x128/’: No file or folder
find: ‘/usr/share/icons/Yaru/32x32/128x128/’: No file or folder
find: ‘/usr/share/icons/Yaru/48x48/128x128/’: No file or folder

My script did not work, and it seemed my codes are not correct. How to locate correctly directories and subdirectories, using function and for condition, to store for fileList and how to make fileList generate correctly the file output with all icons of each subdirectory, and then to remove the files that already exist in Yaru, from Yaru++ and leave only the third-party icons?

9
  • @jsbillings, updated question. I changed to a pure question and added a question at the end of details. Aug 3, 2020 at 2:42
  • There is a lot of intermediate stuff here that doesn't seem to be important. I mean, the finaly question could just be "How to remove the files that already exist in Yaru, from Yaru++ and leave only the third-party icons?" Why is the stuff in between needed?
    – muru
    Aug 3, 2020 at 3:10
  • Also: You seem to be calling fileList $size $directory, but in the fileList function, you have local directory=$1 local size=$2 - why swap the order of arguments?
    – muru
    Aug 3, 2020 at 3:11
  • Also: why would you do for entry in "${search_file[@]}" do for i in *; do echo "${i%.png}"; done, ignoring the entry altogether?
    – muru
    Aug 3, 2020 at 3:16
  • @muru. Our project's users are too demanding and want a minimal icons theme with only third-party icons without including all the original Yaru icons, to reduce the file size: github.com/Bonandry/yaru-plus/issues/48. Aug 3, 2020 at 3:16

1 Answer 1

1

Here's a condensed version that should work:

#! /bin/bash

yaru_original="/UnixStackExchange/usr/share/icons/Yaru"
yaru_plus="/UnixStackExchange/home/gus/GitHub/Yaru++"

# map the Yaru sizes to Yaru++ sizes
declare -A size_mapping=([16x16]=16 [24x24]=24 [32x32]=32 [48x48]=48 [scalable]=symbolic)
declare -a directories=(actions apps categories devices emblems mimetypes places status)

for size in "${!size_mapping[@]}"
do
    for dir in "${directories[@]}"
    do
        for i in "$yaru_original/$size/$dir/"*.{png,svg}
        do
            # Take just the filename ${i##*/} and build the new path
            plus_file=$yaru_plus/$dir/${size_mapping["$size"]}/${i##*/}
            if [[ $plus_file = *.png ]]
            then
                # replce the extension with svg
                plus_file=${plus_file%.png}.svg
            fi
            [[ -f "$plus_file" ]] && echo rm "$plus_file"
        done
    done
done

In the sample given, this detected 13 files out of 50 for removal:

# bash foo.sh
rm /UnixStackExchange/home/gus/GitHub/Yaru++/actions/16/window-close.svg
rm /UnixStackExchange/home/gus/GitHub/Yaru++/apps/16/office.svg
rm /UnixStackExchange/home/gus/GitHub/Yaru++/apps/16/x-office-address-book.svg
rm /UnixStackExchange/home/gus/GitHub/Yaru++/actions/48/window-close.svg
rm /UnixStackExchange/home/gus/GitHub/Yaru++/apps/48/office.svg
rm /UnixStackExchange/home/gus/GitHub/Yaru++/apps/48/x-office-address-book.svg
rm /UnixStackExchange/home/gus/GitHub/Yaru++/actions/symbolic/button-close-symbolic.svg
rm /UnixStackExchange/home/gus/GitHub/Yaru++/actions/symbolic/window-close-symbolic.svg
rm /UnixStackExchange/home/gus/GitHub/Yaru++/apps/symbolic/office-symbolic.svg
rm /UnixStackExchange/home/gus/GitHub/Yaru++/apps/symbolic/x-office-address-book-symbolic.svg
rm /UnixStackExchange/home/gus/GitHub/Yaru++/actions/24/window-close.svg
rm /UnixStackExchange/home/gus/GitHub/Yaru++/apps/24/office.svg
rm /UnixStackExchange/home/gus/GitHub/Yaru++/apps/24/x-office-address-book.svg

Run the script without echo to delete the files. Maybe use rm -i instead of echo rm.

2
  • I have never heard of multidimensional array in Shell Script, it seems to be very rare. I thought it is exclusive of C, C++, Java, Javascript, PHP and Python. Aug 3, 2020 at 4:58
  • 1
    @GustavoReis size_mapping is not a mutlidimensional array, it's an associative array (like a dict in Python or a map in C++). Associative arrays aren't uncommon in bash scripts.
    – muru
    Aug 3, 2020 at 7:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.