我有一个安装应用程序的目录,并且更新符号链接以指向最新版本。
这留下了许多未使用的旧目录,因为没有符号链接指向它。
到目前为止,我一直在使用ls -l
检查并手动删除它们。能够编写此脚本会很有用。
我可以排除符号链接
find -maxdepth 1 \! -type l -exec ls -dl {} +
但是,我不知道如何找出它们所指向的内容并排除它们。
如何列出不包括符号链接的目录和他们指向的目录?
答案1
有了zsh
,你可以这样做:
linktargets=(*(N@:P))
ls -ld -- *(^@e['(($linktargets[(eI)$REPLY:P]))'])
我们创建一个应用于所有符号链接$linktargets
的数组realpath()
,然后传递给ls -ld
不是符号链接且在数组中找不到其真实路径的文件。
另一种不涉及获取实际路径的方法是构建一个所有非符号链接文件的数组,另一个包含符号链接目标的数组,然后将两者相减:
zmodload zsh/stat
non_symlinks=(*(^@))
stat -A symlink_targets +link -- *(@)
ls -ld -- ${non_symlinks:|symlink_targets}
尽管假设符号链接目标不包含任何/
字符(链接是link -> file
,不是link -> ./file
,link -> /path/to/file
...)
答案2
假设 GNUfind
和realpath
, 并且没有带换行符的文件名:
find . -mindepth 1 -maxdepth 1 -exec realpath -e --relative-to=. {} + | sort | uniq -u
这是通过要求realpath
解析所有路径来实现的,使符号链接指向的文件在列表中出现两次。sort | uniq -u
只会保留那些只出现过一次的内容。
小心带有可能指向树外部(或子目录)的符号链接,您可能想了解这些符号链接,但也可以grep -v /
在将任何内容添加| xargs rm -fr
到该管道之前过滤掉;-)。
更好(更标准,但不太明显)的替代方案find . -mindepth 1 -maxdepth 1 ...
是find . ! -name . -prune ...
.
您还可以使用GNU 工具的-z
和选项来支持文件名中的换行符。-0
另请注意,本地化整理实施是破碎的在许多系统上(完全忽略一些特殊字符),因此您最好禁用 和 的任何sort
本地化uniq
。
把它们放在一起:
find . ! -name . -prune -exec realpath -ez --relative-to=. {} + |
grep -zv / |
LC_ALL=C sort -z |
LC_ALL=C uniq -zu |
xargs -r0 do_something