检测并从列表中删除空目录

检测并从列表中删除空目录

游戏开发人员在使用 Unity3D 引擎和 Git 时遇到的一个常见问题是,Unity 和 Git 会争论空目录是否应该存在 - Git 不在乎,Unity3D 会继续为空目录制作 git 可跟踪的 *.meta 文件。基本上意味着如果提交删除文件和目录,开发人员必须手动查找并删除目录和元文件。

我想创建一个 Git 签出后挂钩,以在 Git 删除文件时触发目录删除。

我已经有了一个良好的开端——我知道我需要 Git 做什么。但我不太擅长 shell 脚本编写,并且正在努力使其高效、正确地工作。

我遇到的主要问题是我无法正确理解这一行:

dirs_to_check="($changed_files | xargs dirname | xargs sort -u)"

我希望它将每一行通过管道传输到目录名中,然后获取整个列表并删除重复项。

#!/bin/sh
# This script will be run by Git after a checkout.

# --- Command line
oldRev="$1"
newRev="$2"
isBranchCheckout="$3"

# Grab a list of deleted files:
changed_files="$(git diff-tree -r --name-only --diff-filter=D --no-commit-id $oldRev $newRev)"
# Just testing:
##changed_files="$(git diff-tree -r --name-only --no-commit-id f5865290 eb793b0c)"

# Early exit if there are no removed files at all:
if [ -z "$changed_files" ]; then
    echo "No empty dirs"
    exit 0
fi

echo "$changed_files"
# Get the list of dir paths and then sort and remove dupes: 
dirs_to_check="($changed_files | xargs dirname | xargs sort -u)"

# For each dir check if its empty and if so, remove it:
# TODO: What about the case where the parent dir is also empty of files?
for dir in $dirs_to_check; do
    if [ "$(ls -A $dir)" ]; then
        echo "$dir Not Empty"
    else
        echo "$dir Empty"
        rm $dir
    fi
done

这是一些示例更改的文件如果您想更轻松地测试,请输入以下文本:

test/with dir spaces/debrief/css/style.css
WFTO/uiresources/wftoUI/debrief/debrief.html
WFTO/uiresources/wftoUI/debrief/debrief_specification.js
WFTO/uiresources/wftoUI/debrief/js/debrief.js
WFTO/uiresources/wftoUI/debrief/js/debrief_specification.js
WFTO/uiresources/wftoUI/loading/Loading.css
WFTO/uiresources/wftoUI/loading/Loading.html
WFTO/uiresources/wftoUI/loading/LoadingDLC1.html
WFTO/uiresources/wftoUI/loading/images/HoG-logo.png
WFTO/uiresources/wftoUI/loading/images/background_unused.jpg
WFTO/uiresources/wftoUI/loading/images/banner-patch-1_4.png
WFTO/uiresources/wftoUI/loading/images/bg-back.jpg
WFTO/uiresources/wftoUI/loading/images/bg-front_unused.jpg
WFTO/uiresources/wftoUI/loading/images/bg-front_unused.png
WFTO/uiresources/wftoUI/loading/images/bg-logo.png
WFTO/uiresources/wftoUI/loading/images/dlc1/bg-back.jpg
WFTO/uiresources/wftoUI/loading/images/dlc1/bg-logo.png
WFTO/uiresources/wftoUI/loading/images/dlc1/load-bar-empty.png
WFTO/uiresources/wftoUI/loading/images/dlc1/load-bar-full.png
WFTO/uiresources/wftoUI/loading/images/load-bar-empty.png
WFTO/uiresources/wftoUI/loading/images/load-bar-full.png
WFTO/uiresources/wftoUI/loading/images/loading-background.png
WFTO/uiresources/wftoUI/loading/images/loading-background_unused.jpg
WFTO/uiresources/wftoUI/loading/images/random_loading_pics/Ld0.png
WFTO/uiresources/wftoUI/loading/images/random_loading_pics/Ld1.png
WFTO/uiresources/wftoUI/loading/images/random_loading_pics/Ld10.png

答案1

你可能的意思是

dirs_to_check="$(echo "$changed_files" | xargs dirname | sort -u)"

除非您有数千个目录,否则一个简单的解决方案就是尝试rmdir每个目录并忽略错误。

find . -depth -type d -exec echo rmdir --ignore-fail-on-non-empty {} + 

更改.到相关目录的顶部。如果您的 rmdir 没有忽略选项,只需重定向2>/dev/null即可不显示警告。

答案2

find "$DIR_TO_CLEAN" -type d -empty -delete -print

可以删除 -print 以不获取已删除目录的列表。

编辑:如果您不想删除“$DIR_TO_CLEAN”目录本身,请添加 -mindepth:

find "$DIR_TO_CLEAN" -mindepth 1 -type d -empty -delete -print

相关内容