如何查找指向文件的所有符号链接?

4
这是我的层次结构:
aaaaaaaa
|_q
  |_a.txt
|_w
  |_l1
  |_l2

l1l2是指向a.txt的符号链接。 我运行这段代码来查找在/aaaaaaaa目录下所有指向a.txt的符号链接:

find ~/aaaaaaaa/ -exec ls -a {} ';' | grep '/home/khodor/aaaaaaaa/q/a.txt'

显然这样做是不行的,因为我必须比较文件的真实路径和a.txt的路径。我该如何做到这一点呢?


1
无法完成。未挂载的文件系统中可能存在符号链接。 - stark
3个回答

9
如果您使用GNU/BSD,只需使用-samefile主参数即可。
$ find -L ~/aaaaaaaa/ -samefile ~/aaaaaaaa/q/a.txt 
/home/oguz/aaaaaaaa/q/a.txt
/home/oguz/aaaaaaaa/w/l2
/home/oguz/aaaaaaaa/w/l1

1
referenceid=$(stat -Lc '%d-%i' /home/khodor/aaaaaaaa/q/a.txt)
find ~/aaaaaaaa/ -type l -print0 | while IFS= read -r -d '' filename
do
  if [ "$(stat -Lc '%d-%i' "$filename")" = "$referenceid" ]
  then
    printf -- '%s\n' "$filename"
  fi
done

该程序首先为基础文件获取唯一的ID,例如/home/khodor/aaaaaaaa/q/a.txt。使用stat函数计算该ID,从设备ID和节点号计算而来。

然后,它使用file函数解析您的文件夹,仅限于符号链接(感谢-type l),对于每个文件名,它再次使用stat函数获取设备ID和节点号,使用其-L选项,在提取ID之前解除符号链接引用。

对于与参考ID匹配的每个设备ID和节点号,它打印出文件名。


1
使用find命令和-type l选项来搜索符号链接:
find aaaaaaaa -type l -exec sh -c '
  for i; do
    printf "%s -> %s\n" "$i" "$(readlink -f "$i")"
  done
' sh {} +

该 Shell 脚本使用 readlink -f 打印符号链接的链接路径和规范路径(但您也可以使用 realpath):
示例输出:
aaaaaaaa/w/l1 -> /home/khodor/aaaaaaaa/q/a.txt
aaaaaaaa/w/l2 -> /home/khodor/aaaaaaaa/q/a.txt

使用grep通过绝对路径过滤结果,例如:
find aaaaaaaa -type l -exec sh -c '
  for i; do
    printf "%s -> %s\n" "$i" "$(readlink -f "$i")"
  done
' sh {} + | grep '/home/khodor/aaaaaaaa/q/a.txt$'

请注意模式末尾的$以匹配行尾。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接