用一行删除所有破损的符号链接?

fot*_*nus 51 unix bash shell symlink

对于给定的文件夹,如何删除其中的所有损坏的链接?

我发现这个答案显示了如何删除一个断开的链接,但我不能把它放在一起只有一行.这是否有一个单行?

破坏的符号是指向不再存在的文件/文件夹的链接.

Gil*_*il' 95

这是一种POSIX方法,可以删除当前目录中所有已损坏的符号链接,而不进行递归.它通过告诉find遍历符号链接(-L),但-prune在每个目录或符号链接到这样的停止().

find -L . -name . -o -type d -prune -o -type l -exec rm {} +
Run Code Online (Sandbox Code Playgroud)

您也可以使用shell循环.该测试-L与符号链接匹配,并-e匹配现有文件(不包括损坏的符号链接).

for x in * .[!.]* ..?*; do if [ -L "$x" ] && ! [ -e "$x" ]; then rm -- "$x"; fi; done
Run Code Online (Sandbox Code Playgroud)

如果要递归到子目录,这种技术不起作用.使用GNU find(在非嵌入式Linux和Cygwin上找到),您可以使用-xtype谓词来检测损坏的符号链接(-xtype使用符号链接的目标类型和l断开链接的报告).

find -xtype l -delete
Run Code Online (Sandbox Code Playgroud)

POSIXly,您需要结合两个工具.您可以使用find -type l -exec …在每个符号链接上调用命令,并[ -e "$x" ]测试该链接是否未破坏.

find . -type l -exec sh -c 'for x; do [ -e "$x" ] || rm "$x"; done' _ {} +
Run Code Online (Sandbox Code Playgroud)

最简单的解决方案是使用zsh.要删除当前目录中所有损坏的符号链接:

rm -- *(-@D)
Run Code Online (Sandbox Code Playgroud)

括号中的字符是glob限定符:-取消引用符号链接,@仅匹配符号链接(组合-@仅表示损坏的符号链接),以及D匹配点文件.要递归到子目录,请进行rm -- **/*(-@D).

  • +1非常酷的zsh示例和整体答案.但同样的问题:为什么`rm`而不是`unlink`?不存在`rm`不安全的情况吗? (4认同)
  • 另一种选择:`find -L/path/to/check -type l -delete`(来源:http://www.commandlinefu.com/commands/view/2369/find-broken-symlinks-and-delete-them) (3认同)
  • 为什么此查找表达式不使用-maxdepth来防止递归? (2认同)
  • @billycrook哦,第一个。因为我提供了 POSIX 解决方案,而 POSIX 中没有“-maxdepth”(不过,我认为它计划出现在 SUSv5 中)。 (2认同)

san*_*uel 20

基于您链接的答案(对于给定目录$DIR)的简单答案:

find -L $DIR -maxdepth 1 -type l -delete
Run Code Online (Sandbox Code Playgroud)

  • 我最喜欢这个.甚至查找手册页似乎暗示这是一个找到破坏的符号链接的解决方案. (4认同)
  • 在Mac OS(BSD`find`)上,@ sanmiguel的命令给出了一个错误:`find:-delete:forbidden遵循符号链接 (2认同)
  • @jDub9 `-L` 告诉 `find` 返回符号链接指向的文件的信息,如果它指向的文件不存在,则返回符号链接本身。`-type l` 仅返回符号链接的匹配项,它会立即过滤掉任何存在的链接目标,只留下指向不存在文件的符号链接。 (2认同)

Mr.*_*edy 7

man find示例:

find -L /usr/ports/packages -type l -exec rm -- {} +
Run Code Online (Sandbox Code Playgroud)

删除/ usr/ports/packages中所有损坏的符号链接.


sau*_*hts 7

对于MAC,请执行以下空运行:

DIR=<some path>
find -L $DIR -maxdepth 1 -type l -print
Run Code Online (Sandbox Code Playgroud)

现在,您可以修剪旧的符号链接,如下所示:

for f in `find -L $DIR -maxdepth 1 -type l`; do unlink $f; done
Run Code Online (Sandbox Code Playgroud)


ray*_*phi 5

根据问题"如何找到损坏的符号链接"的接受答案回答:

find . -type l -! -exec test -e {} \; -print | xargs rm
Run Code Online (Sandbox Code Playgroud)


Sam*_*mWN 5

该软件包symlinks已预安装在许多发行版(包括 Ubuntu 16.04 和 Fedora 25)上,并且具有一些非常有用的功能,其中之一正是您正在寻找的功能:

symlinks -d ./
Run Code Online (Sandbox Code Playgroud)
    -d == delete dangling links
Run Code Online (Sandbox Code Playgroud)