Как найти все символические ссылки на файл? - PullRequest
4 голосов
/ 25 февраля 2020

Это моя иерархия:

aaaaaaaa
|_q
  |_a.txt
|_w
  |_l1
  |_l2

l1 и l2 - символические ссылки на a.txt. Я запускаю этот код, чтобы найти все символические ссылки на a.txt в / aaaaaaaa:

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

И он, очевидно, не работает, потому что я должен сравнивать realpath файла с путем a.txt. Каким образом я должен это сделать?

Ответы [ 3 ]

7 голосов
/ 25 февраля 2020

Если у вас есть GNU / BSD, найдите просто -samefile primary.

$ find -L ~/aaaaaaaa/ -samefile ~/aaaaaaaa/q/a.txt 
/home/oguz/aaaaaaaa/q/a.txt
/home/oguz/aaaaaaaa/w/l2
/home/oguz/aaaaaaaa/w/l1
0 голосов
/ 25 февраля 2020

Использование find с -type l для поиска символьных c ссылок:

find aaaaaaaa -type l -exec sh -c '
  for i; do
    printf "%s -> %s\n" "$i" "$(readlink -f "$i")"
  done
' sh {} +

Сценарий оболочки печатает путь ссылки и канонический путь символической ссылки, используя 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$'

Обратите внимание на $ в конце шаблона, чтобы соответствовать концу строки.

0 голосов
/ 25 февраля 2020
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

Первоначально получает уникальный идентификатор для базового файла, например, /home/khodor/aaaaaaaa/q/a.txt. Идентификатор вычисляется из идентификатора устройства и inode, используя stat.

. Затем он анализирует вашу папку с использованием file, ограниченного ссылками символьных c (спасибо -type l), и для для каждого имени файла он получает идентификатор устройства и inode, снова используя stat, используя свою опцию -L, которая разыменовывает ссылку перед извлечением идентификатора.

Для каждого идентификатора устройства и узла, соответствующего идентификатору ссылки, он печатает имя файла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...