如何正确定位目录和子目录并生成每个子目录的所有图标,然后删除已存在的文件?

如何正确定位目录和子目录并生成每个子目录的所有图标,然后删除已存在的文件?

来源

细节

我的脚本基于@btd1337乌拉图图标脚本仅保留第三方图标,但此脚本与我的图标主题项目不兼容,因为:

  • 亚鲁++和规范的亚鲁有不同的层次结构/树;
  • Yaru++ 使用 SVG 格式,Yaru 使用 PNG 格式。

所以我在Shell Script中重写了一个脚本,定位原来Yaru的目录和子目录,将每个子目录的所有图标输出生成文本文件,并进入Yaru++文件夹,列出文本文件以删除已经存在的文件和只保留第三方图标。我还提供了一个压缩文件,以便您在详细信息结束时进行分析。

关注Yaru++和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
    
  • 原始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
    

还要注意一些小细节:

  • 在原始 Yaru 中,大小是文件夹,目录是子文件夹;
  • 在 Yaru++ 中,目录是文件夹,大小是子文件夹;
  • 原始 Yaruscalable/[directories]与 Yaru++ 相同,[directories]/symbolic因为它们的图标都有后缀-symbolic

现在我将在 Shell 脚本中展示脚本的各个部分:

观察directories一下 Yaru 和 Yaru++ 中的情况是一样的。尺寸不同。

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

下一部分将找到原始 Yaru、其文件夹 ( size) 和子文件夹 ( directory),并将存储到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
}

然后它会返回到原来的pwd文件夹所在script位置。

它应该输出如下:

# $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
# ...

然后,函数fileList存储了 function 中的子目录main,并将生成每个子目录的所有不带扩展名的图标的输出(因为 Yaru 使用 PNG 格式,Yaru++ 使用 SVG 格式):

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
}

它应该输出如下:

# $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

观察到我不知道减去x{size}和替换原始 Yaru 数组中不存在的scalable内容。symbolicyaru_original_sizes

文件内actions-16x16.txt

button_cancel
window-close

现在,在最后的聚会中,它将使用awk并打印扩展名来读取文本文件.svg,并将从 Yaru++ 中删除 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

输出awk '{ print $0".svg" }' $home/$size-$directory.txt

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

输出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

我将提供一个小的压缩文件夹以方便您分析:https://github.com/Bondry/yaru-plus/files/5013472/UnixStackExchange.zip

结果

脚本不成功,因为错误输出:

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

我的脚本不起作用,而且我的代码似乎不正确。如何使用函数和for条件正确定位目录和子目录,存储fileList以及如何fileList正确生成带有每个子目录的所有图标的文件输出,然后从 Yaru++ 中删除 Yaru 中已存在的文件并仅保留第三方图标?

答案1

这是一个应该可以工作的精简版本:

#! /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

在给定的示例中,检测到 50 个文件中的 13 个需要删除:

# 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

运行脚本而不echo删除文件。也许使用rm -i而不是echo rm.

相关内容