Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delete all broken symbolic links with a line?

For a given folder, how can I delete all broken links within it?

I found this answer that shows how to delete one broken link, but I can't put that together in only one line. Is there a one-liner for this?

A broken symbolic is a link that points to a file/folder that doesn't exists any longer.

like image 291
fotanus Avatar asked Feb 28 '14 13:02

fotanus


People also ask

Does rm remove symlinks?

The rm command is the dedicated tool for deleting files and directories from the system. Because the symlink itself is a file, we can use the rm command to remove it. The following rm command will remove the symlink. To remove multiple symlinks, use rm as you would to remove multiple files.

Why are my symbolic links broken?

A symlink is broken (or left dangling) when the file at which it points is deleted or moved to another location. If an application's uninstallation routine doesn't work properly, or is interrupted before it completes, you might be left with broken symlinks.

How do I remove a Softlink in Linux?

Remove a Symbolic Link using the rm command You can also use the -i flag with the rm command to prompt for confirmation. After that, you can use the ls -l command to confirm if the symlink has been removed. That is all there is to it!

How do I remove a broken symbolic link Mac?

The best way to remove a symlink is with the appropriately named “unlink” tool. Using unlink to delete a symlink is extremely simple, you just need to point it at the symbolic link to unlink and remove. As always with the command line, be sure your syntax is precise.


2 Answers

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) 
like image 82
Gilles 'SO- stop being evil' Avatar answered Sep 27 '22 22:09

Gilles 'SO- stop being evil'


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

find -L $DIR -maxdepth 1 -type l -delete 
like image 40
sanmiguel Avatar answered Sep 27 '22 22:09

sanmiguel