Is there an easy way to delete all symlinks in a directory using a script (bash with awk or similar..) ?
I have a directory containing both ordinary files and symlinks. Now I want to remove all the symlinks.
(And no, to do it manually is no option...)

I must add that this is on a set-top box and the Linux variant is OpenEmbedded (Enigma2) and so the available
linux command could be a little limited. (They are using busybox for some of the commands as well..)

I could use ls -l | grep lrw to get a list of all the symlinks, but then I'm stuck. Have tried fiddling around with awk, but I have not found any usable solution so far...

Any suggestions ?

Recommended Answers

All 8 Replies

Here is a python script, if you have python

#!/usr/bin/env python
# -*-coding: utf8-*-
from __future__ import (absolute_import, division,
                        print_function, unicode_literals)

__doc__ = '''
'''

import argparse
import os

def main(args):
    d = args.directory
    for n in os.listdir(d):
        f = os.path.join(d, n)
        if os.path.islink(f):
            os.unlink(f)

if __name__ == '__main__':
    parser = argparse.ArgumentParser(
      description="""Remove symbolic links in a directory"""
    )
    parser.add_argument('directory',
        action = 'store',
        help = 'target directory',
        metavar = 'DIRECTORY',
    )
    main(parser.parse_args())

save it as rmsymlinks and make it executable

Or from the command-line you should simply be able to do this:

find ./ -type l -execdir rm {} \;

NOTE: The above will recursively find all sym-links in the current directory (and all sub-directories of the current dir) and remove them with rm. If you only want to find to search the current directory, without going into any subdirectories, you can use the -maxdepth option like this:

find ./ -maxdepth 1 -type l -execdir rm {} \;

Or you could put it into a shellscript:

#!/bin/sh

find /path/to/folder/ -maxdepth 1 -type l -execdir rm {} \;

etc...

EDIT:
For extra safety, you might also want to consider using the -i switch/option with the rm command. This will prompt whether you want to delete each individual file.
e.g.

find ./ -maxdepth 1 -type l -execdir rm -i {} \;

I wouldn't want you to accidentally hose your system using any of my suggestions! ;)

Gribouilis: Your python-script gives me an error when executing:
./rmsymlinks: line 3: syntax error: unexpected "(".

Additional systeminformation for my system (for your information):
Python 2.7.2 (default, Jul 24 2014, 08:43:32)
[GCC 4.6.4 20120303 (prerelease)] on linux2

JasonHippy: The option "execdir" is not a part of the find-command in busybox on my set-top-box. .. Sorry.

JasonHippy: Since all the symlinks are in the same directory (no subdirectories) I'm able to use your command with 'exec' replacing 'execdir'. And it works! :-)

There is no syntax error for my python. However, remove lines 3 to 8 if you want, they're not used.

Are you sure that the shebang works ?

I could try that at a later time. Now I'll stick with the other solution... :-)

Your set-top-box must either be using a different implementation or a much older version of find that doesn't have the execdir option. It was added to GNU find as a safer alternative to exec. But exec will do the trick if execdir is not available.

From looking at the man page for find, there is also the -delete option, which I've never noticed before. As you have no need for the maxdepth option, that would leave you with this:

find ./ -type l -delete

Which is even more concise and requires a little less typing. (If your set-top-boxes version of find supports it that is!)

Also, for the sake of completeness:
Depending on the age of the tools that are installed on your set-top-box, some of the commands might not be able to handle file-names containing spaces very well. So the examples I've posted so far could be problematic if any of your files contain spaces in their names.
If files with spaces in their names are a problem to remove, another alternative would be to pipe the list of files output by find to the rm command using xargs:

find ./ -type l -print0 | xargs -0 rm

Finds print0 option will print the full path of each file found, with a null character appended at the end (as opposed to a newline). And then in xargs, the -0 parameter (or --null) will cause xargs to read all characters up to the null character as a single parameter/file-name. So effectively, each filename will be separated/terminated by a null character - allowing file-names containing spaces to be passed to rm. Otherwise, the rm command would treat the spaces as separators, so a file with spaces in its name would be treated as several file-names, which could be problematic.

This might not be an issue for you, but I mentioned it just in case! :)

I'm running BusyBox version 1.19.4 (2014-07-24 09:45:52 CEST) on my set-top-box. The find-command is contained in the multi-call binary.

The command 'find ./ -type l -delete' works as well.
:-)

commented: compact solution +14
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.