用一行删除所有中断的符号链接?

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

我找到了 这个答案,它显示了如何删除一个坏掉的链接,但我不能把它放在一起,只有一行。有什么俏皮话吗?

中断符号是指向不再存在的文件/文件夹的链接。

59643 次浏览

You could use readlink to determine if a symlink is broken or not.

The following would list all the broken symlinks in a given directory (and subdirectories):

find . -type l -exec sh -c 'readlink -f "{}" 1>/dev/null || echo "{}"' -- "{}" \;

Replace echo with rm to get rid of the broken ones!

(I've redirected the output of readlink to /dev/null so as to avoid confusion; it'd list the target for the symlinks.)

Here's a POSIX way of deleting all broken symbolic links in the current directory, without recursion. It works by telling find to traverse symbolic links (-L), but stopping (-prune) at every directory-or-symbolic-link-to-such.

find -L . -name . -o -type d -prune -o -type l -exec rm {} +

You can also use a shell loop. The test -L matches symbolic links, and -e matches existing files (excluding broken symlinks).

for x in * .[!.]* ..?*; do if [ -L "$x" ] && ! [ -e "$x" ]; then rm -- "$x"; fi; done

If you want to recurse into subdirectories, this technique doesn't work. With GNU find (as found on non-embedded Linux and Cygwin), you can use the -xtype predicate to detect broken symbolic links (-xtype uses the type of the target for symbolic links, and reports l for broken links).

find -xtype l -delete

POSIXly, you need to combine two tools. You can use find -type l -exec … to invoke a command on each symbolic link, and [ -e "$x" ] to test whether that link is non-broken.

find . -type l -exec sh -c 'for x; do [ -e "$x" ] || rm "$x"; done' _ {} +

The simplest solution is to use zsh. To delete all broken symbolic links in the current directory:

rm -- *(-@D)

The characters in parentheses are glob qualifiers: - to dereference symlinks, @ to match only symlinks (the combination -@ means broken symlinks only), and D to match dot files. To recurse into subdirectories, make that:

rm -- **/*(-@D)

Simple answer based on the answer you linked (for a given directory, $DIR):

find -L $DIR -maxdepth 1 -type l -delete

Answer based on the accepted answer to the question question "How can I find broken symlinks":

find . -type l -! -exec test -e {} \; -print | xargs rm

From man find EXAMPLES:

find -L /usr/ports/packages -type l -exec rm -- {} +

Delete all broken symbolic links in /usr/ports/packages.

The package symlinks is pre-installed on many distributions (including Ubuntu 16.04 & Fedora 25) and has some really useful features, one of which does precisely what you're looking for:

symlinks -d ./
    -d == delete dangling links

For MAC, do a dry run as follows:-

DIR=<some path>
find -L $DIR -maxdepth 1 -type l -print

Now, you can prune the old symlinks as follows:-

for f in `find -L $DIR -maxdepth 1 -type l`; do unlink $f; done

You can try using rmlint.

First, change directory to the folder that contains broken symlinks, and then run the following commands to find bad symlinks pointing nowhere:

rmlint --types="badlinks"

Then rmlint will create a bash script rmlint.sh in your current directory and print a list of bad symlinks in your terminal. To delete all the bad symlinks in your current directory, you can run

./rmlint.sh

Not exactly one liner, but it is very easy to use.

This answer is based on @sanmiguel's but with fd

fd -tl -L $DIR -X rm