List files by symlink target

findsymlink

How do I get list of files (and then do something with that list) by filtering through the symbolic link target name, and not the symlink name? For example from the following list I'm only interested in the first four files (target contains bar):

foo ->  /tmp/bar
bar ->  /home/me/bartoo
baz ->  /home/me/public/barthree
zoo ->  /usr/share/bar
moo ->  /tmp/foo
roc ->  /tmp/roc

Best Answer

You can use find to fetch all files of type symlink and add the -ilname option to search by name of the link destination. This works just like -iname but for the link target name instead of the link name.

find -type l -ilname "*bar*"

That will still print out the name of the link, not the target. If you want to print the names of the targets, try this:

find -type l -ilname "*bar*" -printf "%l\n"

Or get a full ls style output

find -type l -ilname "*bar*" -ls

What you mean by "do something with the list" is unclear, but if you wanted to operate on the link files, you could use the -exec argument to find:

find -type l -ilname "*bar*" -exec touch {} \;

But if you need to operate on the link targets, you will need to use the -printf to get the target values and then xargs or some loop yourself to operate. You could do something like this:

find -type l -printf "%l\n" | grep bar | xargs touch

... which also demonstrates how to use grep instead of find -ilname to do your name matching, although you could do that either way.