Here's a solution using find
and some bash features:
shopt -s extglob
find . -type l | while read -r; do
t="$(readlink "$REPLY")"
if [[ "$t" != /* ]]; then
t="${REPLY%%*([^/])}$t"
fi
[ -L "$t" ] && echo "$REPLY"
done
Or all in one line:
find . -type l | while read -r; do t="$(readlink "$REPLY")"; if [[ "$t" != /* ]]; then t="${REPLY%%*([^/])}$t"; fi; [ -L "$t" ] && echo "$REPLY"; done
find . -type l
finds all symlinks.
- Then for each symlink
$REPLY
, we get its target $t
using readlink
.
- If the target is not an absolute name (doesn't start with
/
), we prepend the dirname from the original path $REPLY
(the expression ${REPLY%%*([^/])}
removes all trailing non-slash characters).
- If the target is also a symlink (
-L
), we output the original name $REPLY
.
The extglob
extension must be enabled to get *([^/])
to work.