有没有什么优雅的方法可以只查找指向目录的符号链接,而不是其他文件?

有没有什么优雅的方法可以只查找指向目录的符号链接,而不是其他文件?

find -type lls -l | grep '^l'显示符号链接,但不区分指向目录的符号链接和指向文件的符号链接。做这样的事情的一种非常笨拙的方法是,find -type l -exec file -L '{}' ';' | grep directory但效率非常低。

有没有更好的方法来仅查找指向目录的符号链接?

答案1

根据的 POSIX 规范test-d测试为:

为真,如果路径名解析为目录的现有目录条目。

因此,一旦有了符号链接,就可以使用[ -d ... ]它:

find . -type l -exec test -d {} \; -print

或者,避免为每个链接执行外部命令:

find . -type l -exec sh -c 'for l; do [ -d "$l" ] && printf "%s\n" "$l"; done' _ {} +

答案2

您可以-type l与 一起使用-xtype d。 (不过我不知道是否-xtype是 POSIX。)

答案3

为了桀骜用户,这可以很容易地实现使用全局限定符 (@-/):

for F in **/*(N@-/); do the_thing "$F"; done

分解该表达式:**/*glob 递归地匹配所有文件/目录,不包括隐藏的文件/目录。(expr)在 glob 将匹配限制为满足特定条件的文件之后。这里的标准是:

  • N:在该扩展中启用 nullglob,这样如果没有匹配的文件,它就会扩展为空而不是导致错误。当在for循环或数组赋值中使用 glob 时,通常需要使用该限定符。
  • @: 只匹配符号链接
  • -:从测试链接本身切换到测试链接目标
  • /: 只匹配目录

示例输出,在我的系统上运行/etc/

% ls -ldF -- **/*(@-/)
lrwxrwxrwx 1 root root 46 Sep 22  2022 alternatives/desktop-plasma5-wallpaper -> /usr/share/desktop-base/active-theme/wallpaper/
lrwxrwxrwx 1 root root 39 Sep 22  2022 alternatives/desktop-theme -> /usr/share/desktop-base/homeworld-theme/
lrwxrwxrwx 1 root root 36 Sep 22  2022 alternatives/vendor-logos -> /usr/share/desktop-base/debian-logos/
lrwxrwxrwx 1 root root 11 Sep 22  2022 runit/runsvdir/default/ssh -> /etc/sv/ssh/
lrwxrwxrwx 1 root root 18 Aug  7  2022 xdg/systemd/user -> ../../systemd/user/

请注意,这也匹配指向指向目录的链接的链接,而不仅仅是直接链接。

答案4

这是我的版本,应该比find . -type l -exec test -d {} \; -print许多链接更有效:

$ find / -type l -print0 |
xargs -0 stat -L -c'%F %n' |
awk '$1 == "directory" { print substr($0, 11) }'

它找到所有链接,将它们输入stat以确定文件类型,然后awk过滤目录,只留下文件名。

如果没有awk你得到类似的东西:

directory /sys/module/libnvdimm/holders/nfit

确认:

$ ll /sys/module/libnvdimm/holders/nfit
lrwxrwxrwx 1 root root 0 Oct 20 13:49 /sys/module/libnvdimm/holders/nfit -> ../../nfit
$ readlink -f /sys/module/libnvdimm/holders/nfit
/sys/module/nfit
$ ll -d /sys/module/nfit
drwxr-xr-x 6 root root 0 Oct 16 20:45 /sys/module/nfit

相关内容