How do I remove all symlinks in a folder (dozens of them) at once? It's not practical to insert every single one of them by hand when using unlink or rm.
4 Answers
You can use the find-command to do that:
find /path/to/directory -maxdepth 1 -type l -delete
To be on the safe side, check first without the -delete-option:
find /path/to/directory -maxdepth 1 -type l
-maxdepth 1 ensures that find will look only in /path/to/directory but not in it's subfolders for symlinks. Feel free to take a look at man find.
- 18,644
List the links in the current directory alias folder and check that you really want to remove them,
find -type l -ls # search also in subdirectories
find -maxdepth 1 -type l -ls # search only in the directory itself
If things look good, and you want to delete these links, run
find -type l -delete # delete also in subdirectories
find -maxdepth 1 -type l -delete # delete only in the directory itself
If you want to delete interactively, you can use the following command line (this is safer)
find -type l -exec rm -i {} + # delete also in subdirectories
find -maxdepth 1 -type l -exec rm -i {} + # delete only in the directory itself
- 47,684
For users of the Z shell, rm *(@) will achieve this.
Zsh supports glob qualifiers that limit the type of files a glob (such as *) applies to, for example (/) for directories, (x) for executable files, (L0) for empty files, and (@) for symlinks.
For symlinks:
% ll
lrwxrwxrwx 1 test test 3 Aug 8 15:51 bar -> foo
-rw-r--r-- 1 test test 0 Aug 8 15:51 baz
-rw-r--r-- 1 test test 0 Aug 8 15:52 foo
lrwxrwxrwx 1 test test 4 Aug 8 15:51 qux -> /etc/
% rm *(@)
removed 'bar'
removed 'qux'
% ll
-rw-r--r-- 1 test test 0 Aug 8 15:51 baz
-rw-r--r-- 1 test test 0 Aug 8 15:52 foo
- 940
- 7
- 11
In bash(and most shells) … The builtin command test and its variant [ has an option -h(or -L if it’s easier to remember) that will return success(exit 0) for a file if it exists and is a symbolic link … So it can be used in a shell loop like so:
for f in *
do
if [ -h "$f" ]
then
echo rm -- "$f"
fi
done
or a one liner like so:
for f in *; do if [ -h "$f" ]; then echo rm -- "$f"; fi done
or even more compact(bash specific … although reported to be working in zsh and ksh as well) like so:
for f in *; { [ -h "$f" ] && echo rm -- "$f"; }
Notice:
echo is there for a dry-run ... When satisfied with the output, remove echo to delete the links.
- 34,963