20

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.

  • What do you mean by "folder"? Are you just talking about what Linux calls directories, or do you have some other usage in mind? – tchrist Aug 08 '22 at 14:46

4 Answers4

34

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.

mook765
  • 15,925
14

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

sudodus
  • 46,324
  • 5
  • 88
  • 152
  • 2
    With the first interactive option, you may also want to use -depth to ensure depth-first traversal - that is, that it asks about root/symlink1/symlink2 before root/symlink1. – minnmass Aug 08 '22 at 03:24
  • 1
    @minnmass: But find won't follow symlinks by default, so it won't find root/symlink1/symlink2 - it'll find root/symlink1, but not try to look for things under it (even if it's a link to a directory). – psmears Aug 08 '22 at 11:02
  • @psmears: derp; I'm too used to treating symlinks to directories as just directories, and the abstraction broke. ... never mind. – minnmass Aug 08 '22 at 13:42
  • Was going to comment exactly this but not quite as complete... beat me to it – dolt Aug 09 '22 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. – dolt Aug 09 '22 at 19:29
10

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

marcelm
  • 702
  • 6
  • 9
  • 2
    Nice :-) … probably a dry-run with echo first before using rm might be a good idea to be on the safe side. – Raffa Aug 08 '22 at 15:47
7

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.

Raffa
  • 32,237
  • 1
    A bit more compact: [ -h "$f" ] && rm -- "$f" – Pablo Bianchi Aug 08 '22 at 16:06
  • @PabloBianchi Yep, … only a bit though :-) … But, can be compacted more if the command grouping constructs {} are used with the for loop … https://askubuntu.com/a/1419265 – Raffa Aug 08 '22 at 16:14