删除目录,除非由符号链接指向

删除目录,除非由符号链接指向

我有以下目录结构。我需要找到存在名为 的文件的目录log.xml,并完全删除所有目录,除了特定符号链接指向的目录之外。

例如,/dir1/main/app1/v004//dir1/main/app2/v004/log.xml由符号链接指向,因此不应删除它们。

另外,如何删除除符号链接指向之外的目录,而无需找到log.xml.

您能帮忙提供正确的解决方案吗?

/dir1/main/app1/v001/
/dir1/main/app1/v002/log.xml
/dir1/main/app1/v003/log.xml
/dir1/main/app1/v004/log.xml
/dir1/main/app1/v005/log.xml
/dir1/ln1/app -> /dir1/main/app2/v004

/dir1/main/app2/v001/
/dir1/main/app2/v002/log.xml
/dir1/main/app2/v003/log.xml
/dir1/main/app2/v004/log.xml
/dir1/main/app2/v005/log.xml
/dir1/ln2/app -> /dir1/main/app2/v004

答案1

app假设您要删除目录中除v001(不包含log.xml) 和v004(符号链接指向的)之外的所有子目录:

for topdir in /dir1 /dir2; do

    for dirpath in "$topdir"/main/app/*/; do
            if [ -e "$dirpath/log.xml" ] && ! [ "$dirpath" -ef "$topdir"/ln/app ]
            then
                    printf 'Would remove "%s"\n' "$dirpath"
                    # rm -rf "$dirpath"
            fi
    done

done

外部循环用于循环遍历两个最顶层的目录/dir1/dir2您可能希望将/dir[12]其用作通配模式)。顶级目录的名称保存在topdir变量中。

内循环迭代下面的子目录app,underlying $topdir。如果子目录包含名为log.xml(第一个测试, with -e)的内容,并且符号链接未指向该目录"$topdir"/ln/app(第二个测试, with -ef),则可以将其删除。

-e测试是对给定路径名是否存在的标准测试。该-ef测试是非标准的,但由bashshell 实现,它在解析符号链接后测试两个路径名是否引用同一文件(或本例中的目录)。

为了安全起见,实际删除已被注释掉。在启用该命令之前,您应该对之前备份的数据进行测试rm

要删除子目录,无论它们是否包含名为 的内容log.xml,请删除-e测试,以便if语句看起来像

if ! [ "$dirpath" -ef "$topdir"/ln/app ]; then
        printf 'Would remove "%s"\n' "$dirpath"
        # rm -rf "$dirpath"
fi

答案2

GNUfind有一个选项-samefile,您需要包含 -L 选项才能使其工作。

看一下下面两个命令的输出

(cd /dir1 ; find -L . -samefile ln/app ) # your file and link

(cd /dir1 ; find -L . -not -samefile ln/app ) # everything other than your file and link

第二个应该生成您要删除的文件的列表。也许您只想列出文件而不是目录,如果是这样,那么只需添加-type f

find -L . -type f -samefile ln/app)

删除文件很简单,只需在 find 命令后附加一个 exec 操作,例如-exec rm -v {} \;

相关内容