4

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,471
2IRN
  • 755

2 Answers2

9

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,426
  • oh nice, I couldn't figure out how to get the -links test to take "more than 1" (obviously I did not try hard enough). I don't think you need to specify -k1 to sort since it will sort on the first column anyway – Zanna May 01 '17 at 10:03
  • Yeah, I figure it out from -size usage ;) – Ravexina May 01 '17 at 10:06
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,471