I have created symlinks to a large amount of logfiles. The syntax of the logfiles is yyyymmdd.log.gz.

To simplify things I use a simple sequence without parsing it with date:

for dd in $(seq -w 20150101 20151231) ; do 
     ln -s $origin/$dd.log.gz $target/$dd.log.gz

How do I get rid of all the broken symlinks I just created in a single fell swoop?


This simple one liner does the job quite fast, requires GNU find:

find . -xtype l -delete

A bit of explanation:

-xtype l tests for links that are broken (it is the opposite of -type)

-delete deletes the files directly, no need for further bothering with xargs or -exec

NOTE: -xtype l means -xtype low case L (as in link) ;)

GNU Findutils: Find

  • 1
    Took me a second to notice it's a lower case L and not 1, on -xtype l. – Telmo Marques Feb 2 '19 at 18:40
  • 1
    thx, I wrote a small note. – runlevel0 Feb 8 '19 at 10:35

With zsh (you're actually using zsh syntax in your code; with bash, you'd need to quote those variables):

rm -- $target/*(-@)


rm -- $target/<20150101-20151231>.log.gz(-@)

*(@) matches the files of type symlink. *(-@) are the ones that are still of type symlink after symlink resolution (that is, those for which the target of the symlink can't be resolved). That's equivalent to GNU find's -xtype l.

In zsh and with GNU ln, you'd rather write your loop as:

ln -srt $target -- $origin/<20150101-20151231>.log.gz

Which would also work even if $origin contains a relative path (and creates relative symlinks which reduces the risk of symlinks to be broken if some path components of the origin (the ones that are common with that of the target) are renamed in the future).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.