3

How can I list all files with hardlinks and the associated paths?

It should be a sorted list, by the inode ID.

EDIT: sure, I mean all files with a hardlink number >=2

I thought about a list like

INODE_ID   FILEPATH

1234 /tmp/test1
1234 /tmp/test2
3245 /tmp/test4
3245 /tmp/test3
Zanna
  • 72,312
2IRN
  • 745

2 Answers2

8

Here is my solution with find:

find . -links +1 -type f -name '*' -printf '%i %p\n' | sort
  • . : search in current directory, you can change it to anything else, e.g: /, ~/ravexina, etc.
  • -links +1 : only files with more than of 1 link ( >= 2 ).
  • -type f : only files (not directories, sym links, pipe files, etc).
  • -name '*': all files with anything in their names no matter what.
  • -printf '%i %p\n': only print inode, file path and a new line\n.
  • sort : sort lines based on inodes.
Ravexina
  • 57,256
1

OK, in that case maybe

for i in /tmp/**; do 
  [[ -f "$i" ]] && 
  (( $(stat -c %h "$i") > 1 )) && 
  stat -c '%i %n' "$i"
done | sort -V

Notes

  • for i in * for each file in the current directory
  • [[ -f "$i" ]] && if it is a regular file and
  • (( $(stat -c %h "$i") > 1 )) if it has more than one hard link
  • stat -c '%i %n' print its inode number and name
  • | sort -V and sort that output "naturally"

You can replace * with the path to the files, for example /tmp/* which will cause the full path to be printed. If you want to search recursively, you can use shopt -s globstar and then ** in the path, for example /tmp/**

find has a -links test but it seems to only take an integer you'll have to read Ravexina's answer for a solution that uses it.

Zanna
  • 72,312