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
.
-
1Thanks. "find /path/to/directory -maxdepth 1 -type l -delete" did the trick. Aug 8, 2022 at 8:44
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
-
2With the first interactive option, you may also want to use
-depth
to ensure depth-first traversal - that is, that it asks aboutroot/symlink1/symlink2
beforeroot/symlink1
.– minnmassAug 8, 2022 at 3:24 -
1@minnmass: But
find
won't follow symlinks by default, so it won't findroot/symlink1/symlink2
- it'll findroot/symlink1
, but not try to look for things under it (even if it's a link to a directory).– psmearsAug 8, 2022 at 11:02 -
@psmears: derp; I'm too used to treating symlinks to directories as just directories, and the abstraction broke. ... never mind.– minnmassAug 8, 2022 at 13:42
-
Was going to comment exactly this but not quite as complete... beat me to it 🙃– doltAug 9, 2022 at 19:25
-
1@minnmass 'find' by default won't search directories that are symlinks to outside the root dir. You can use -L to tell it to dereference symlinks which iirc works for directories.– doltAug 9, 2022 at 19:29
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
-
2Nice :-) … probably a dry-run with
echo
first before usingrm
might be a good idea to be on the safe side.– RaffaAug 8, 2022 at 15:47
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.
-
1
-
@PabloBianchi Yep, … only a bit though :-) … But, can be compacted more if the command grouping constructs
{}
are used with thefor
loop … askubuntu.com/a/1419265– RaffaAug 8, 2022 at 16:14